mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-09-22 16:04:28 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce17fff1ac | ||
|
|
2d55da309b | ||
|
|
761207155d | ||
|
|
456a879181 | ||
|
|
2e02e70916 | ||
|
|
dbc803a0d9 | ||
|
|
fdccafaa68 | ||
|
|
deebd82ecd | ||
|
|
0906abdea9 | ||
|
|
da94fe4f6f | ||
|
|
79672a28ee | ||
|
|
e052a4b261 | ||
|
|
425d4e8fed | ||
|
|
d2a2e2304d | ||
|
|
e7157a64ed | ||
|
|
245a995203 | ||
|
|
c29d7fb6a2 | ||
|
|
8cada6d0a2 | ||
|
|
d03446beef | ||
|
|
f62c0b4ca8 | ||
|
|
c046056736 | ||
|
|
e63cbf94d0 | ||
|
|
d48247b7c6 | ||
|
|
695dcd5de7 | ||
|
|
5e35985a3f | ||
|
|
d9325819fd | ||
|
|
f960238b47 | ||
|
|
d0aef5b683 | ||
|
|
c69fc95126 | ||
|
|
51cb41975b | ||
|
|
0debbb83b1 | ||
|
|
fbfe2b0a31 | ||
|
|
a719a83bce | ||
|
|
d353a9cb9d | ||
|
|
ee2e07a9a3 | ||
|
|
f6689043c7 | ||
|
|
45531dc54a | ||
|
|
0a26c192fe |
+5
-18
@@ -8,8 +8,9 @@ cache:
|
||||
- $HOME/.m2
|
||||
env:
|
||||
global:
|
||||
- secure: "IfYURwZaDWuBDvyn47n0k1Zod/IQw1FF+CS5nnV08Q+NfC3vGGJMwV8m59XnbfwnWGxwvCaAbk4qP6s6+ijgZNKkvgfFMo3rfTok5zt43bIqgaFOANYV+OC/1c59gYD6ZUxhW5iNgMgU3qdsRtJuwSmfkVv/jKyLGfAbS4kN8BA=" #coverity
|
||||
- secure: "lV9OwUbHMrMpLUH1CY+Z4puLDdFXytudyPlG1eGRsesdpuG6KM3uQVz6uAtf6lrU8DRbMM/T7ML+PmvQ4UoPPYLdLxESLLBat2qUPOIVBOhTSlCc7I0DmGy04CSvkeMy8dPaQC0ukgNiR7zwoNzfcpGRN/U9S8tziDruuHoZSrg=" #bintray
|
||||
- secure: "IfYURwZaDWuBDvyn47n0k1Zod/IQw1FF+CS5nnV08Q+NfC3vGGJMwV8m59XnbfwnWGxwvCaAbk4qP6s6+ijgZNKkvgfFMo3rfTok5zt43bIqgaFOANYV+OC/1c59gYD6ZUxhW5iNgMgU3qdsRtJuwSmfkVv/jKyLGfAbS4kN8BA=" # COVERITY_SCAN_TOKEN
|
||||
- secure: "lV9OwUbHMrMpLUH1CY+Z4puLDdFXytudyPlG1eGRsesdpuG6KM3uQVz6uAtf6lrU8DRbMM/T7ML+PmvQ4UoPPYLdLxESLLBat2qUPOIVBOhTSlCc7I0DmGy04CSvkeMy8dPaQC0ukgNiR7zwoNzfcpGRN/U9S8tziDruuHoZSrg=" # BINTRAY_API_KEY
|
||||
- secure: "oWFgRTVP6lyTa7qVxlvkpm20MtVc3BtmsNXQJS6bfg2A0o/iCQMNx7OD59BaafCLGRKvCcJVESiC8FlSylVMS7CDSyYu0gg70NUiIuHp4NBM5inFWYCy/PdQsCTzr5uvNG+rMFQpMFRaCV0FrfM3tLondcVkhsHL68l93Xoexx4=" # CODACY_PROJECT_TOKEN
|
||||
addons:
|
||||
coverity_scan:
|
||||
project:
|
||||
@@ -19,24 +20,10 @@ addons:
|
||||
branch_pattern: release.*
|
||||
install:
|
||||
# "clean" needed until https://bugs.openjdk.java.net/browse/JDK-8067747 is resolved.
|
||||
- mvn -fmain/pom.xml clean package -DskipTests dependency:go-offline -Ptest-coverage
|
||||
- mvn -fmain/pom.xml clean package -DskipTests dependency:go-offline -Pcoverage
|
||||
- mvn -fmain/pom.xml clean package -DskipTests dependency:go-offline -Prelease
|
||||
script:
|
||||
- mvn --update-snapshots -fmain/pom.xml -Ptest-coverage clean test jacoco:report-aggregate
|
||||
after_success:
|
||||
- "bash <(curl -s https://codecov.io/bash)"
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/7d429ab35361726e26f2
|
||||
on_success: change
|
||||
on_failure: always
|
||||
on_start: false
|
||||
slack:
|
||||
rooms:
|
||||
secure: "lngJ/HEAFBbD5AdiO9avMqptKpZHdmEwOzS9FabZjkdFh7yAYueTk5RniPUvShjsKtThYm7cJ8AtDMDwc07NvPrzbMBRtUJGwuDT+7c7YFALGFJ1NYi+emkC9x1oafvmPgEYSE+tMKzNcwrHi3ytGgKdIotsKwaF35QNXYA9aMs="
|
||||
on_success: change
|
||||
on_failure: always
|
||||
- mvn --update-snapshots -fmain/pom.xml clean test jacoco:report verify -Pcoverage
|
||||
before_deploy:
|
||||
- mvn -fmain/pom.xml -Prelease clean package -DskipTests
|
||||
deploy:
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
[](https://travis-ci.org/cryptomator/cryptomator)
|
||||
[](https://scan.coverity.com/projects/cryptomator-cryptomator)
|
||||
[](https://www.codacy.com/app/cryptomator/cryptomator?utm_source=github.com&utm_medium=referral&utm_content=cryptomator/cryptomator&utm_campaign=Badge_Grade)
|
||||
[](https://coveralls.io/github/cryptomator/cryptomator?branch=master)
|
||||
[](https://gitter.im/cryptomator/cryptomator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](http://twitter.com/Cryptomator)
|
||||
[](https://poeditor.com/join/project/bHwbvJmx0E)
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.3.0-rc1</version>
|
||||
<version>1.3.0-rc4</version>
|
||||
</parent>
|
||||
<artifactId>ant-kit</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2015 Markus Kreusch
|
||||
This file is licensed under the terms of the MIT license.
|
||||
See the LICENSE.txt file for more info.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.2.4</version>
|
||||
</parent>
|
||||
<artifactId>commons-test</artifactId>
|
||||
<name>Cryptomator common test dependencies</name>
|
||||
<description>Shared utilities for tests</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>commons</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.bechte.junit</groupId>
|
||||
<artifactId>junit-hierarchicalcontextrunner</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-all</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
+1
-10
@@ -10,7 +10,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.3.0-rc1</version>
|
||||
<version>1.3.0-rc4</version>
|
||||
</parent>
|
||||
<artifactId>commons</artifactId>
|
||||
<name>Cryptomator Commons</name>
|
||||
@@ -53,13 +53,4 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package org.cryptomator.common;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class CachingSupplier<T> implements Supplier<T> {
|
||||
|
||||
public static <T> Supplier<T> from(Supplier<T> delegate) {
|
||||
return new CachingSupplier<>(delegate);
|
||||
}
|
||||
|
||||
private Supplier<T> delegate;
|
||||
|
||||
private CachingSupplier(Supplier<T> delegate) {
|
||||
this.delegate = () -> {
|
||||
T result = delegate.get();
|
||||
CachingSupplier.this.delegate = () -> result;
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
return delegate.get();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package org.cryptomator.common;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class Holder<V> implements Supplier<V>, Consumer<V> {
|
||||
|
||||
private final V initial;
|
||||
|
||||
private V value;
|
||||
|
||||
public <W extends V> Holder(W initial) {
|
||||
this.initial = initial;
|
||||
reset();
|
||||
}
|
||||
|
||||
public V get() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void set(V value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
set(initial);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(V value) {
|
||||
set(value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
|
||||
public final class LazyInitializer {
|
||||
|
||||
private LazyInitializer() {
|
||||
@@ -41,11 +43,9 @@ public final class LazyInitializer {
|
||||
try {
|
||||
return reference.updateAndGet(invokeFactoryIfNull(factory));
|
||||
} catch (InitializationException e) {
|
||||
if (exceptionType.isInstance(e.getCause())) {
|
||||
throw exceptionType.cast(e.getCause());
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
Throwables.throwIfUnchecked(e);
|
||||
Throwables.throwIfInstanceOf(e.getCause(), exceptionType);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,9 +55,8 @@ public final class LazyInitializer {
|
||||
if (currentValue == null) {
|
||||
try {
|
||||
return factory.get();
|
||||
} catch (RuntimeException e) {
|
||||
throw e; // don't catch unchecked exceptions
|
||||
} catch (Exception e) {
|
||||
Throwables.throwIfUnchecked(e); // don't catch unchecked exceptions
|
||||
throw new InitializationException(e);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
package org.cryptomator.common;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
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.
|
||||
*
|
||||
* @param <T> the type of the input to the function
|
||||
* @param <R> the type of the result of the function
|
||||
* @param function An {@code Optional}-bearing input function {@code Function<Foo, Optional<Bar>>}
|
||||
* @return A {@code Function<Foo, Bar>}, that may throw a NoSuchElementException, if the original function returns an empty optional.
|
||||
*/
|
||||
public static <T, R> Function<T, R> unwrap(Function<T, Optional<R>> function) {
|
||||
return t -> function.apply(t).get();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Markus Kreusch and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Kreusch - initial implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Utility to print stack traces while analyzing issues.
|
||||
*
|
||||
* @author Markus Kreusch
|
||||
*/
|
||||
public class StackTrace {
|
||||
|
||||
public static void print(String message) {
|
||||
Thread thread = Thread.currentThread();
|
||||
System.err.println(stackTraceFor(message, thread));
|
||||
}
|
||||
|
||||
private static String stackTraceFor(String message, Thread thread) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
appendMessageAndThreadName(result, message, thread);
|
||||
appendStackTrace(thread, result);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private static void appendStackTrace(Thread thread, StringBuilder result) {
|
||||
Stream.of(thread.getStackTrace()) //
|
||||
.skip(4) //
|
||||
.forEach(stackTraceElement -> append(stackTraceElement, result));
|
||||
}
|
||||
|
||||
private static void appendMessageAndThreadName(StringBuilder result, String message, Thread thread) {
|
||||
result //
|
||||
.append('[') //
|
||||
.append(thread.getName()) //
|
||||
.append("] ") //
|
||||
.append(message);
|
||||
}
|
||||
|
||||
private static void append(StackTraceElement stackTraceElement, StringBuilder result) {
|
||||
String className = stackTraceElement.getClassName();
|
||||
String methodName = stackTraceElement.getMethodName();
|
||||
String fileName = stackTraceElement.getFileName();
|
||||
int lineNumber = stackTraceElement.getLineNumber();
|
||||
result.append('\n') //
|
||||
.append(className).append(':').append(methodName) //
|
||||
.append(" (").append(fileName).append(':').append(lineNumber).append(')');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package org.cryptomator.common;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.util.concurrent.ExecutionError;
|
||||
import com.google.common.util.concurrent.UncheckedExecutionException;
|
||||
|
||||
public class WeakValuedCache<Key, Value> {
|
||||
|
||||
private final LoadingCache<Key, Value> delegate;
|
||||
|
||||
private WeakValuedCache(Function<Key, Value> loader) {
|
||||
delegate = CacheBuilder.newBuilder() //
|
||||
.weakValues() //
|
||||
.build(new CacheLoader<Key, Value>() {
|
||||
@Override
|
||||
public Value load(Key key) {
|
||||
return loader.apply(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static <Key, Value> WeakValuedCache<Key, Value> usingLoader(Function<Key, Value> loader) {
|
||||
return new WeakValuedCache<>(loader);
|
||||
}
|
||||
|
||||
public Value get(Key key) {
|
||||
try {
|
||||
return delegate.get(key);
|
||||
} catch (ExecutionException e) {
|
||||
throw new IllegalStateException("No checked exception can be thrown by loader", e);
|
||||
} catch (UncheckedExecutionException e) {
|
||||
throw (RuntimeException) e.getCause();
|
||||
} catch (ExecutionError e) {
|
||||
throw (Error) e.getCause();
|
||||
}
|
||||
}
|
||||
|
||||
public void forEach(BiConsumer<Key, Value> function) {
|
||||
delegate.asMap().forEach(function);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,6 +10,8 @@ package org.cryptomator.common.settings;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
@@ -27,25 +29,24 @@ public class Settings {
|
||||
public static final int MAX_PORT = 65535;
|
||||
public static final boolean DEFAULT_CHECK_FOR_UDPATES = true;
|
||||
public static final int DEFAULT_PORT = 42427;
|
||||
public static final boolean DEFAULT_USE_IPV6 = false;
|
||||
public static final boolean DEFAULT_USE_IPV6 = SystemUtils.IS_OS_WINDOWS;
|
||||
public static final int DEFAULT_NUM_TRAY_NOTIFICATIONS = 3;
|
||||
public static final String DEFAULT_GVFS_SCHEME = "dav";
|
||||
public static final boolean DEFAULT_DEBUG_MODE = false;
|
||||
|
||||
private final Consumer<Settings> saveCmd;
|
||||
private final ObservableList<VaultSettings> directories = FXCollections.observableArrayList();
|
||||
private final ObservableList<VaultSettings> directories = FXCollections.observableArrayList(VaultSettings::observables);
|
||||
private final BooleanProperty checkForUpdates = new SimpleBooleanProperty(DEFAULT_CHECK_FOR_UDPATES);
|
||||
private final IntegerProperty port = new SimpleIntegerProperty(DEFAULT_PORT);
|
||||
private final BooleanProperty useIpv6 = new SimpleBooleanProperty(DEFAULT_USE_IPV6);
|
||||
private final IntegerProperty numTrayNotifications = new SimpleIntegerProperty(DEFAULT_NUM_TRAY_NOTIFICATIONS);
|
||||
private final StringProperty preferredGvfsScheme = new SimpleStringProperty(DEFAULT_GVFS_SCHEME);
|
||||
private final BooleanProperty debugMode = new SimpleBooleanProperty(DEFAULT_DEBUG_MODE);
|
||||
private Consumer<Settings> saveCmd;
|
||||
|
||||
/**
|
||||
* Package-private constructor; use {@link SettingsProvider}.
|
||||
*/
|
||||
Settings(Consumer<Settings> saveCmd) {
|
||||
this.saveCmd = saveCmd;
|
||||
Settings() {
|
||||
directories.addListener((ListChangeListener.Change<? extends VaultSettings> change) -> this.save());
|
||||
checkForUpdates.addListener(this::somethingChanged);
|
||||
port.addListener(this::somethingChanged);
|
||||
@@ -55,6 +56,10 @@ public class Settings {
|
||||
debugMode.addListener(this::somethingChanged);
|
||||
}
|
||||
|
||||
void setSaveCmd(Consumer<Settings> saveCmd) {
|
||||
this.saveCmd = saveCmd;
|
||||
}
|
||||
|
||||
private void somethingChanged(ObservableValue<?> observable, Object oldValue, Object newValue) {
|
||||
this.save();
|
||||
}
|
||||
|
||||
+8
-11
@@ -8,7 +8,6 @@ package org.cryptomator.common.settings;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -22,13 +21,8 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SettingsJsonAdapter.class);
|
||||
|
||||
private final Consumer<Settings> saveCmd;
|
||||
private final VaultSettingsJsonAdapter vaultSettingsJsonAdapter = new VaultSettingsJsonAdapter();
|
||||
|
||||
public SettingsJsonAdapter(Consumer<Settings> saveCmd) {
|
||||
this.saveCmd = saveCmd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(JsonWriter out, Settings value) throws IOException {
|
||||
out.beginObject();
|
||||
@@ -53,14 +47,14 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
|
||||
|
||||
@Override
|
||||
public Settings read(JsonReader in) throws IOException {
|
||||
Settings settings = new Settings(saveCmd);
|
||||
Settings settings = new Settings();
|
||||
|
||||
in.beginObject();
|
||||
while (in.hasNext()) {
|
||||
String name = in.nextName();
|
||||
switch (name) {
|
||||
case "directories":
|
||||
settings.getDirectories().addAll(readVaultSettingsArray(in, settings));
|
||||
settings.getDirectories().addAll(readVaultSettingsArray(in));
|
||||
break;
|
||||
case "checkForUpdatesEnabled":
|
||||
settings.checkForUpdates().set(in.nextBoolean());
|
||||
@@ -69,7 +63,10 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
|
||||
settings.port().set(in.nextInt());
|
||||
break;
|
||||
case "useIpv6":
|
||||
settings.useIpv6().set(in.nextBoolean());
|
||||
// Temporarily we will disable loading this setting, as we want the default value on each app start.
|
||||
// This setting might be removed completely in the future
|
||||
// settings.useIpv6().set(in.nextBoolean());
|
||||
in.skipValue();
|
||||
break;
|
||||
case "numTrayNotifications":
|
||||
settings.numTrayNotifications().set(in.nextInt());
|
||||
@@ -90,11 +87,11 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
|
||||
return settings;
|
||||
}
|
||||
|
||||
private List<VaultSettings> readVaultSettingsArray(JsonReader in, Settings settings) throws IOException {
|
||||
private List<VaultSettings> readVaultSettingsArray(JsonReader in) throws IOException {
|
||||
List<VaultSettings> result = new ArrayList<>();
|
||||
in.beginArray();
|
||||
while (!JsonToken.END_ARRAY.equals(in.peek())) {
|
||||
result.add(vaultSettingsJsonAdapter.read(in, settings));
|
||||
result.add(vaultSettingsJsonAdapter.read(in));
|
||||
}
|
||||
in.endArray();
|
||||
return result;
|
||||
|
||||
@@ -62,7 +62,7 @@ public class SettingsProvider implements Provider<Settings> {
|
||||
private final ScheduledExecutorService saveScheduler = Executors.newSingleThreadScheduledExecutor();
|
||||
private final AtomicReference<ScheduledFuture<?>> scheduledSaveCmd = new AtomicReference<>();
|
||||
private final AtomicReference<Settings> settings = new AtomicReference<>();
|
||||
private final SettingsJsonAdapter settingsJsonAdapter = new SettingsJsonAdapter(this::scheduleSave);
|
||||
private final SettingsJsonAdapter settingsJsonAdapter = new SettingsJsonAdapter();
|
||||
private final Gson gson;
|
||||
|
||||
@Inject
|
||||
@@ -100,8 +100,9 @@ public class SettingsProvider implements Provider<Settings> {
|
||||
LOG.info("Settings loaded from " + settingsPath);
|
||||
} catch (IOException e) {
|
||||
LOG.info("Failed to load settings, creating new one.");
|
||||
settings = new Settings(this::scheduleSave);
|
||||
settings = new Settings();
|
||||
}
|
||||
settings.setSaveCmd(this::scheduleSave);
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,37 +15,36 @@ import java.util.UUID;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
||||
public class VaultSettings {
|
||||
|
||||
private final Settings settings;
|
||||
public static final boolean DEFAULT_UNLOCK_AFTER_STARTUP = false;
|
||||
public static final boolean DEFAULT_MOUNT_AFTER_UNLOCK = true;
|
||||
public static final boolean DEFAULT_REAVEAL_AFTER_MOUNT = true;
|
||||
|
||||
private final String id;
|
||||
private final ObjectProperty<Path> path = new SimpleObjectProperty<>();
|
||||
private final StringProperty mountName = new SimpleStringProperty();
|
||||
private final StringProperty winDriveLetter = new SimpleStringProperty();
|
||||
private final BooleanProperty mountAfterUnlock = new SimpleBooleanProperty();
|
||||
private final BooleanProperty revealAfterMount = new SimpleBooleanProperty();
|
||||
private final BooleanProperty unlockAfterStartup = new SimpleBooleanProperty(DEFAULT_UNLOCK_AFTER_STARTUP);
|
||||
private final BooleanProperty mountAfterUnlock = new SimpleBooleanProperty(DEFAULT_MOUNT_AFTER_UNLOCK);
|
||||
private final BooleanProperty revealAfterMount = new SimpleBooleanProperty(DEFAULT_REAVEAL_AFTER_MOUNT);
|
||||
|
||||
public VaultSettings(Settings settings, String id) {
|
||||
this.settings = settings;
|
||||
public VaultSettings(String id) {
|
||||
this.id = Objects.requireNonNull(id);
|
||||
|
||||
EasyBind.subscribe(path, this::deriveMountNameFromPath);
|
||||
path.addListener(this::somethingChanged);
|
||||
mountName.addListener(this::somethingChanged);
|
||||
winDriveLetter.addListener(this::somethingChanged);
|
||||
mountAfterUnlock.addListener(this::somethingChanged);
|
||||
}
|
||||
|
||||
private void somethingChanged(ObservableValue<?> observable, Object oldValue, Object newValue) {
|
||||
settings.save();
|
||||
Observable[] observables() {
|
||||
return new Observable[] {path, mountName, winDriveLetter, unlockAfterStartup, mountAfterUnlock, revealAfterMount};
|
||||
}
|
||||
|
||||
private void deriveMountNameFromPath(Path path) {
|
||||
@@ -54,8 +53,8 @@ public class VaultSettings {
|
||||
}
|
||||
}
|
||||
|
||||
public static VaultSettings withRandomId(Settings settings) {
|
||||
return new VaultSettings(settings, generateId());
|
||||
public static VaultSettings withRandomId() {
|
||||
return new VaultSettings(generateId());
|
||||
}
|
||||
|
||||
private static String generateId() {
|
||||
@@ -112,6 +111,10 @@ public class VaultSettings {
|
||||
return winDriveLetter;
|
||||
}
|
||||
|
||||
public BooleanProperty unlockAfterStartup() {
|
||||
return unlockAfterStartup;
|
||||
}
|
||||
|
||||
public BooleanProperty mountAfterUnlock() {
|
||||
return mountAfterUnlock;
|
||||
}
|
||||
|
||||
+10
-4
@@ -24,18 +24,20 @@ class VaultSettingsJsonAdapter {
|
||||
out.name("path").value(value.path().get().toString());
|
||||
out.name("mountName").value(value.mountName().get());
|
||||
out.name("winDriveLetter").value(value.winDriveLetter().get());
|
||||
out.name("unlockAfterStartup").value(value.unlockAfterStartup().get());
|
||||
out.name("mountAfterUnlock").value(value.mountAfterUnlock().get());
|
||||
out.name("revealAfterMount").value(value.revealAfterMount().get());
|
||||
out.endObject();
|
||||
}
|
||||
|
||||
public VaultSettings read(JsonReader in, Settings settings) throws IOException {
|
||||
public VaultSettings read(JsonReader in) throws IOException {
|
||||
String id = null;
|
||||
String path = null;
|
||||
String mountName = null;
|
||||
String winDriveLetter = null;
|
||||
boolean mountAfterUnlock = true;
|
||||
boolean revealAfterMount = true;
|
||||
boolean unlockAfterStartup = VaultSettings.DEFAULT_UNLOCK_AFTER_STARTUP;
|
||||
boolean mountAfterUnlock = VaultSettings.DEFAULT_MOUNT_AFTER_UNLOCK;
|
||||
boolean revealAfterMount = VaultSettings.DEFAULT_REAVEAL_AFTER_MOUNT;
|
||||
|
||||
in.beginObject();
|
||||
while (in.hasNext()) {
|
||||
@@ -53,6 +55,9 @@ class VaultSettingsJsonAdapter {
|
||||
case "winDriveLetter":
|
||||
winDriveLetter = in.nextString();
|
||||
break;
|
||||
case "unlockAfterStartup":
|
||||
unlockAfterStartup = in.nextBoolean();
|
||||
break;
|
||||
case "mountAfterUnlock":
|
||||
mountAfterUnlock = in.nextBoolean();
|
||||
break;
|
||||
@@ -66,10 +71,11 @@ class VaultSettingsJsonAdapter {
|
||||
}
|
||||
in.endObject();
|
||||
|
||||
VaultSettings vaultSettings = (id == null) ? VaultSettings.withRandomId(settings) : new VaultSettings(settings, id);
|
||||
VaultSettings vaultSettings = (id == null) ? VaultSettings.withRandomId() : new VaultSettings(id);
|
||||
vaultSettings.mountName().set(mountName);
|
||||
vaultSettings.path().set(Paths.get(path));
|
||||
vaultSettings.winDriveLetter().set(winDriveLetter);
|
||||
vaultSettings.unlockAfterStartup().set(unlockAfterStartup);
|
||||
vaultSettings.mountAfterUnlock().set(mountAfterUnlock);
|
||||
vaultSettings.revealAfterMount().set(revealAfterMount);
|
||||
return vaultSettings;
|
||||
|
||||
-178
@@ -1,178 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import static org.cryptomator.common.streams.AutoClosingStreamFactory.AUTO_CLOSING_STREAM_FACTORY;
|
||||
|
||||
import java.util.DoubleSummaryStatistics;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.DoubleBinaryOperator;
|
||||
import java.util.function.DoubleConsumer;
|
||||
import java.util.function.DoublePredicate;
|
||||
import java.util.function.ObjDoubleConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.DoubleStream;
|
||||
|
||||
public class AutoClosingDoubleStream extends DelegatingDoubleStream {
|
||||
|
||||
public static DoubleStream from(DoubleStream delegate) {
|
||||
return new AutoClosingDoubleStream(delegate);
|
||||
}
|
||||
|
||||
public AutoClosingDoubleStream(DoubleStream delegate) {
|
||||
super(delegate, AUTO_CLOSING_STREAM_FACTORY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(DoubleConsumer action) {
|
||||
try {
|
||||
super.forEach(action);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachOrdered(DoubleConsumer action) {
|
||||
try {
|
||||
super.forEachOrdered(action);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] toArray() {
|
||||
try {
|
||||
return super.toArray();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double reduce(double identity, DoubleBinaryOperator op) {
|
||||
try {
|
||||
return super.reduce(identity, op);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalDouble reduce(DoubleBinaryOperator op) {
|
||||
try {
|
||||
return super.reduce(op);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R collect(Supplier<R> supplier, ObjDoubleConsumer<R> accumulator, BiConsumer<R, R> combiner) {
|
||||
try {
|
||||
return super.collect(supplier, accumulator, combiner);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double sum() {
|
||||
try {
|
||||
return super.sum();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalDouble min() {
|
||||
try {
|
||||
return super.min();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalDouble max() {
|
||||
try {
|
||||
return super.max();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count() {
|
||||
try {
|
||||
return super.count();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalDouble average() {
|
||||
try {
|
||||
return super.average();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DoubleSummaryStatistics summaryStatistics() {
|
||||
try {
|
||||
return super.summaryStatistics();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean anyMatch(DoublePredicate predicate) {
|
||||
try {
|
||||
return super.anyMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allMatch(DoublePredicate predicate) {
|
||||
try {
|
||||
return super.allMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean noneMatch(DoublePredicate predicate) {
|
||||
try {
|
||||
return super.noneMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalDouble findFirst() {
|
||||
try {
|
||||
return super.findFirst();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalDouble findAny() {
|
||||
try {
|
||||
return super.findAny();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import static org.cryptomator.common.streams.AutoClosingStreamFactory.AUTO_CLOSING_STREAM_FACTORY;
|
||||
|
||||
import java.util.IntSummaryStatistics;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.IntBinaryOperator;
|
||||
import java.util.function.IntConsumer;
|
||||
import java.util.function.IntPredicate;
|
||||
import java.util.function.ObjIntConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class AutoClosingIntStream extends DelegatingIntStream {
|
||||
|
||||
public static IntStream from(IntStream delegate) {
|
||||
return new AutoClosingIntStream(delegate);
|
||||
}
|
||||
|
||||
public AutoClosingIntStream(IntStream delegate) {
|
||||
super(delegate, AUTO_CLOSING_STREAM_FACTORY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(IntConsumer action) {
|
||||
try {
|
||||
super.forEach(action);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachOrdered(IntConsumer action) {
|
||||
try {
|
||||
super.forEachOrdered(action);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] toArray() {
|
||||
try {
|
||||
return super.toArray();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int reduce(int identity, IntBinaryOperator op) {
|
||||
try {
|
||||
return super.reduce(identity, op);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalInt reduce(IntBinaryOperator op) {
|
||||
try {
|
||||
return super.reduce(op);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R collect(Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R, R> combiner) {
|
||||
try {
|
||||
return super.collect(supplier, accumulator, combiner);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int sum() {
|
||||
try {
|
||||
return super.sum();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalInt min() {
|
||||
try {
|
||||
return super.min();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalInt max() {
|
||||
try {
|
||||
return super.max();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count() {
|
||||
try {
|
||||
return super.count();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalDouble average() {
|
||||
try {
|
||||
return super.average();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntSummaryStatistics summaryStatistics() {
|
||||
try {
|
||||
return super.summaryStatistics();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean anyMatch(IntPredicate predicate) {
|
||||
try {
|
||||
return super.anyMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allMatch(IntPredicate predicate) {
|
||||
try {
|
||||
return super.allMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean noneMatch(IntPredicate predicate) {
|
||||
try {
|
||||
return super.noneMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalInt findFirst() {
|
||||
try {
|
||||
return super.findFirst();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalInt findAny() {
|
||||
try {
|
||||
return super.findAny();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import static org.cryptomator.common.streams.AutoClosingStreamFactory.AUTO_CLOSING_STREAM_FACTORY;
|
||||
|
||||
import java.util.LongSummaryStatistics;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.LongBinaryOperator;
|
||||
import java.util.function.LongConsumer;
|
||||
import java.util.function.LongPredicate;
|
||||
import java.util.function.ObjLongConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.LongStream;
|
||||
|
||||
public class AutoClosingLongStream extends DelegatingLongStream {
|
||||
|
||||
public static LongStream from(LongStream delegate) {
|
||||
return new AutoClosingLongStream(delegate);
|
||||
}
|
||||
|
||||
public AutoClosingLongStream(LongStream delegate) {
|
||||
super(delegate, AUTO_CLOSING_STREAM_FACTORY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(LongConsumer action) {
|
||||
try {
|
||||
super.forEach(action);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachOrdered(LongConsumer action) {
|
||||
try {
|
||||
super.forEachOrdered(action);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] toArray() {
|
||||
try {
|
||||
return super.toArray();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long reduce(long identity, LongBinaryOperator op) {
|
||||
try {
|
||||
return super.reduce(identity, op);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalLong reduce(LongBinaryOperator op) {
|
||||
try {
|
||||
return super.reduce(op);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R collect(Supplier<R> supplier, ObjLongConsumer<R> accumulator, BiConsumer<R, R> combiner) {
|
||||
try {
|
||||
return super.collect(supplier, accumulator, combiner);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long sum() {
|
||||
try {
|
||||
return super.sum();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalLong min() {
|
||||
try {
|
||||
return super.min();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalLong max() {
|
||||
try {
|
||||
return super.max();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count() {
|
||||
try {
|
||||
return super.count();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalDouble average() {
|
||||
try {
|
||||
return super.average();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LongSummaryStatistics summaryStatistics() {
|
||||
try {
|
||||
return super.summaryStatistics();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean anyMatch(LongPredicate predicate) {
|
||||
try {
|
||||
return super.anyMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allMatch(LongPredicate predicate) {
|
||||
try {
|
||||
return super.allMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean noneMatch(LongPredicate predicate) {
|
||||
try {
|
||||
return super.noneMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalLong findFirst() {
|
||||
try {
|
||||
return super.findFirst();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalLong findAny() {
|
||||
try {
|
||||
return super.findAny();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import static org.cryptomator.common.streams.AutoClosingStreamFactory.AUTO_CLOSING_STREAM_FACTORY;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A Stream which is automatically closed after execution of a terminal operation.
|
||||
* <p>
|
||||
* Streams returned by intermediate operations are also auto closing.
|
||||
* <p>
|
||||
* <b>Note:</b> When using {@link #iterator()} or {@link #spliterator()} auto closing does not occur.
|
||||
*
|
||||
* @author Markus Kreusch
|
||||
*/
|
||||
public class AutoClosingStream<T> extends DelegatingStream<T> {
|
||||
|
||||
public static <T> Stream<T> from(Stream<T> delegate) {
|
||||
return new AutoClosingStream<>(delegate);
|
||||
}
|
||||
|
||||
private AutoClosingStream(Stream<T> delegate) {
|
||||
super(delegate, AUTO_CLOSING_STREAM_FACTORY);
|
||||
}
|
||||
|
||||
public void forEach(Consumer<? super T> action) {
|
||||
try {
|
||||
super.forEach(action);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public void forEachOrdered(Consumer<? super T> action) {
|
||||
try {
|
||||
super.forEachOrdered(action);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public Object[] toArray() {
|
||||
try {
|
||||
return super.toArray();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public <A> A[] toArray(IntFunction<A[]> generator) {
|
||||
try {
|
||||
return super.toArray(generator);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public T reduce(T identity, BinaryOperator<T> accumulator) {
|
||||
try {
|
||||
return super.reduce(identity, accumulator);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<T> reduce(BinaryOperator<T> accumulator) {
|
||||
try {
|
||||
return super.reduce(accumulator);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner) {
|
||||
try {
|
||||
return super.reduce(identity, accumulator, combiner);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public <R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner) {
|
||||
try {
|
||||
return super.collect(supplier, accumulator, combiner);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public <R, A> R collect(Collector<? super T, A, R> collector) {
|
||||
try {
|
||||
return super.collect(collector);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<T> min(Comparator<? super T> comparator) {
|
||||
try {
|
||||
return super.min(comparator);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<T> max(Comparator<? super T> comparator) {
|
||||
try {
|
||||
return super.max(comparator);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public long count() {
|
||||
try {
|
||||
return super.count();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean anyMatch(Predicate<? super T> predicate) {
|
||||
try {
|
||||
return super.anyMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean allMatch(Predicate<? super T> predicate) {
|
||||
try {
|
||||
return super.allMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean noneMatch(Predicate<? super T> predicate) {
|
||||
try {
|
||||
return super.noneMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<T> findFirst() {
|
||||
try {
|
||||
return super.findFirst();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<T> findAny() {
|
||||
try {
|
||||
return super.findAny();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class AutoClosingStreamFactory implements DelegatingStreamFactory {
|
||||
|
||||
public static final DelegatingStreamFactory AUTO_CLOSING_STREAM_FACTORY = new AutoClosingStreamFactory();
|
||||
|
||||
private AutoClosingStreamFactory() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> Stream<S> from(Stream<S> other) {
|
||||
if (AutoClosingStream.class.isInstance(other)) {
|
||||
return other;
|
||||
} else {
|
||||
return AutoClosingStream.from(other);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntStream from(IntStream other) {
|
||||
if (AutoClosingIntStream.class.isInstance(other)) {
|
||||
return other;
|
||||
} else {
|
||||
return AutoClosingIntStream.from(other);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LongStream from(LongStream other) {
|
||||
if (AutoClosingLongStream.class.isInstance(other)) {
|
||||
return other;
|
||||
} else {
|
||||
return AutoClosingLongStream.from(other);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DoubleStream from(DoubleStream other) {
|
||||
if (AutoClosingDoubleStream.class.isInstance(other)) {
|
||||
return other;
|
||||
} else {
|
||||
return AutoClosingDoubleStream.from(other);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-179
@@ -1,179 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import java.util.DoubleSummaryStatistics;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.PrimitiveIterator.OfDouble;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.DoubleBinaryOperator;
|
||||
import java.util.function.DoubleConsumer;
|
||||
import java.util.function.DoubleFunction;
|
||||
import java.util.function.DoublePredicate;
|
||||
import java.util.function.DoubleToIntFunction;
|
||||
import java.util.function.DoubleToLongFunction;
|
||||
import java.util.function.DoubleUnaryOperator;
|
||||
import java.util.function.ObjDoubleConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
abstract class DelegatingDoubleStream implements DoubleStream {
|
||||
|
||||
private final DoubleStream delegate;
|
||||
private final DelegatingStreamFactory wrapper;
|
||||
|
||||
public DelegatingDoubleStream(DoubleStream delegate, DelegatingStreamFactory wrapper) {
|
||||
this.delegate = delegate;
|
||||
this.wrapper = wrapper;
|
||||
}
|
||||
|
||||
public DoubleStream filter(DoublePredicate predicate) {
|
||||
return wrapper.from(delegate.filter(predicate));
|
||||
}
|
||||
|
||||
public boolean isParallel() {
|
||||
return delegate.isParallel();
|
||||
}
|
||||
|
||||
public DoubleStream map(DoubleUnaryOperator mapper) {
|
||||
return wrapper.from(delegate.map(mapper));
|
||||
}
|
||||
|
||||
public <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
|
||||
return wrapper.from(delegate.mapToObj(mapper));
|
||||
}
|
||||
|
||||
public DoubleStream unordered() {
|
||||
return wrapper.from(delegate.unordered());
|
||||
}
|
||||
|
||||
public DoubleStream onClose(Runnable closeHandler) {
|
||||
return wrapper.from(delegate.onClose(closeHandler));
|
||||
}
|
||||
|
||||
public IntStream mapToInt(DoubleToIntFunction mapper) {
|
||||
return wrapper.from(delegate.mapToInt(mapper));
|
||||
}
|
||||
|
||||
public LongStream mapToLong(DoubleToLongFunction mapper) {
|
||||
return wrapper.from(delegate.mapToLong(mapper));
|
||||
}
|
||||
|
||||
public void close() {
|
||||
delegate.close();
|
||||
}
|
||||
|
||||
public DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper) {
|
||||
return wrapper.from(delegate.flatMap(mapper));
|
||||
}
|
||||
|
||||
public DoubleStream distinct() {
|
||||
return wrapper.from(delegate.distinct());
|
||||
}
|
||||
|
||||
public DoubleStream sorted() {
|
||||
return wrapper.from(delegate.sorted());
|
||||
}
|
||||
|
||||
public DoubleStream peek(DoubleConsumer action) {
|
||||
return wrapper.from(delegate.peek(action));
|
||||
}
|
||||
|
||||
public DoubleStream limit(long maxSize) {
|
||||
return wrapper.from(delegate.limit(maxSize));
|
||||
}
|
||||
|
||||
public DoubleStream skip(long n) {
|
||||
return wrapper.from(delegate.skip(n));
|
||||
}
|
||||
|
||||
public void forEach(DoubleConsumer action) {
|
||||
delegate.forEach(action);
|
||||
}
|
||||
|
||||
public void forEachOrdered(DoubleConsumer action) {
|
||||
delegate.forEachOrdered(action);
|
||||
}
|
||||
|
||||
public double[] toArray() {
|
||||
return delegate.toArray();
|
||||
}
|
||||
|
||||
public double reduce(double identity, DoubleBinaryOperator op) {
|
||||
return delegate.reduce(identity, op);
|
||||
}
|
||||
|
||||
public OptionalDouble reduce(DoubleBinaryOperator op) {
|
||||
return delegate.reduce(op);
|
||||
}
|
||||
|
||||
public <R> R collect(Supplier<R> supplier, ObjDoubleConsumer<R> accumulator, BiConsumer<R, R> combiner) {
|
||||
return delegate.collect(supplier, accumulator, combiner);
|
||||
}
|
||||
|
||||
public double sum() {
|
||||
return delegate.sum();
|
||||
}
|
||||
|
||||
public OptionalDouble min() {
|
||||
return delegate.min();
|
||||
}
|
||||
|
||||
public OptionalDouble max() {
|
||||
return delegate.max();
|
||||
}
|
||||
|
||||
public long count() {
|
||||
return delegate.count();
|
||||
}
|
||||
|
||||
public OptionalDouble average() {
|
||||
return delegate.average();
|
||||
}
|
||||
|
||||
public DoubleSummaryStatistics summaryStatistics() {
|
||||
return delegate.summaryStatistics();
|
||||
}
|
||||
|
||||
public boolean anyMatch(DoublePredicate predicate) {
|
||||
return delegate.anyMatch(predicate);
|
||||
}
|
||||
|
||||
public boolean allMatch(DoublePredicate predicate) {
|
||||
return delegate.allMatch(predicate);
|
||||
}
|
||||
|
||||
public boolean noneMatch(DoublePredicate predicate) {
|
||||
return delegate.noneMatch(predicate);
|
||||
}
|
||||
|
||||
public OptionalDouble findFirst() {
|
||||
return delegate.findFirst();
|
||||
}
|
||||
|
||||
public OptionalDouble findAny() {
|
||||
return delegate.findAny();
|
||||
}
|
||||
|
||||
public Stream<Double> boxed() {
|
||||
return wrapper.from(delegate.boxed());
|
||||
}
|
||||
|
||||
public DoubleStream sequential() {
|
||||
return wrapper.from(delegate.sequential());
|
||||
}
|
||||
|
||||
public DoubleStream parallel() {
|
||||
return wrapper.from(delegate.parallel());
|
||||
}
|
||||
|
||||
public OfDouble iterator() {
|
||||
return delegate.iterator();
|
||||
}
|
||||
|
||||
public java.util.Spliterator.OfDouble spliterator() {
|
||||
return delegate.spliterator();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,188 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import java.util.IntSummaryStatistics;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.PrimitiveIterator.OfInt;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.IntBinaryOperator;
|
||||
import java.util.function.IntConsumer;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.IntPredicate;
|
||||
import java.util.function.IntToDoubleFunction;
|
||||
import java.util.function.IntToLongFunction;
|
||||
import java.util.function.IntUnaryOperator;
|
||||
import java.util.function.ObjIntConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
abstract class DelegatingIntStream implements IntStream {
|
||||
|
||||
private final IntStream delegate;
|
||||
private final DelegatingStreamFactory wrapper;
|
||||
|
||||
public DelegatingIntStream(IntStream delegate, DelegatingStreamFactory wrapper) {
|
||||
this.delegate = delegate;
|
||||
this.wrapper = wrapper;
|
||||
}
|
||||
|
||||
public IntStream filter(IntPredicate predicate) {
|
||||
return wrapper.from(delegate.filter(predicate));
|
||||
}
|
||||
|
||||
public boolean isParallel() {
|
||||
return delegate.isParallel();
|
||||
}
|
||||
|
||||
public IntStream map(IntUnaryOperator mapper) {
|
||||
return wrapper.from(delegate.map(mapper));
|
||||
}
|
||||
|
||||
public <U> Stream<U> mapToObj(IntFunction<? extends U> mapper) {
|
||||
return wrapper.from(delegate.mapToObj(mapper));
|
||||
}
|
||||
|
||||
public IntStream unordered() {
|
||||
return wrapper.from(delegate.unordered());
|
||||
}
|
||||
|
||||
public LongStream mapToLong(IntToLongFunction mapper) {
|
||||
return wrapper.from(delegate.mapToLong(mapper));
|
||||
}
|
||||
|
||||
public IntStream onClose(Runnable closeHandler) {
|
||||
return wrapper.from(delegate.onClose(closeHandler));
|
||||
}
|
||||
|
||||
public DoubleStream mapToDouble(IntToDoubleFunction mapper) {
|
||||
return wrapper.from(delegate.mapToDouble(mapper));
|
||||
}
|
||||
|
||||
public void close() {
|
||||
delegate.close();
|
||||
}
|
||||
|
||||
public IntStream flatMap(IntFunction<? extends IntStream> mapper) {
|
||||
return wrapper.from(delegate.flatMap(mapper));
|
||||
}
|
||||
|
||||
public IntStream distinct() {
|
||||
return wrapper.from(delegate.distinct());
|
||||
}
|
||||
|
||||
public IntStream sorted() {
|
||||
return wrapper.from(delegate.sorted());
|
||||
}
|
||||
|
||||
public IntStream peek(IntConsumer action) {
|
||||
return wrapper.from(delegate.peek(action));
|
||||
}
|
||||
|
||||
public IntStream limit(long maxSize) {
|
||||
return wrapper.from(delegate.limit(maxSize));
|
||||
}
|
||||
|
||||
public IntStream skip(long n) {
|
||||
return wrapper.from(delegate.skip(n));
|
||||
}
|
||||
|
||||
public void forEach(IntConsumer action) {
|
||||
delegate.forEach(action);
|
||||
}
|
||||
|
||||
public void forEachOrdered(IntConsumer action) {
|
||||
delegate.forEachOrdered(action);
|
||||
}
|
||||
|
||||
public int[] toArray() {
|
||||
return delegate.toArray();
|
||||
}
|
||||
|
||||
public int reduce(int identity, IntBinaryOperator op) {
|
||||
return delegate.reduce(identity, op);
|
||||
}
|
||||
|
||||
public OptionalInt reduce(IntBinaryOperator op) {
|
||||
return delegate.reduce(op);
|
||||
}
|
||||
|
||||
public <R> R collect(Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R, R> combiner) {
|
||||
return delegate.collect(supplier, accumulator, combiner);
|
||||
}
|
||||
|
||||
public int sum() {
|
||||
return delegate.sum();
|
||||
}
|
||||
|
||||
public OptionalInt min() {
|
||||
return delegate.min();
|
||||
}
|
||||
|
||||
public OptionalInt max() {
|
||||
return delegate.max();
|
||||
}
|
||||
|
||||
public long count() {
|
||||
return delegate.count();
|
||||
}
|
||||
|
||||
public OptionalDouble average() {
|
||||
return delegate.average();
|
||||
}
|
||||
|
||||
public IntSummaryStatistics summaryStatistics() {
|
||||
return delegate.summaryStatistics();
|
||||
}
|
||||
|
||||
public boolean anyMatch(IntPredicate predicate) {
|
||||
return delegate.anyMatch(predicate);
|
||||
}
|
||||
|
||||
public boolean allMatch(IntPredicate predicate) {
|
||||
return delegate.allMatch(predicate);
|
||||
}
|
||||
|
||||
public boolean noneMatch(IntPredicate predicate) {
|
||||
return delegate.noneMatch(predicate);
|
||||
}
|
||||
|
||||
public OptionalInt findFirst() {
|
||||
return delegate.findFirst();
|
||||
}
|
||||
|
||||
public OptionalInt findAny() {
|
||||
return delegate.findAny();
|
||||
}
|
||||
|
||||
public LongStream asLongStream() {
|
||||
return wrapper.from(delegate.asLongStream());
|
||||
}
|
||||
|
||||
public DoubleStream asDoubleStream() {
|
||||
return wrapper.from(delegate.asDoubleStream());
|
||||
}
|
||||
|
||||
public Stream<Integer> boxed() {
|
||||
return wrapper.from(delegate.boxed());
|
||||
}
|
||||
|
||||
public IntStream sequential() {
|
||||
return wrapper.from(delegate.sequential());
|
||||
}
|
||||
|
||||
public IntStream parallel() {
|
||||
return wrapper.from(delegate.parallel());
|
||||
}
|
||||
|
||||
public OfInt iterator() {
|
||||
return delegate.iterator();
|
||||
}
|
||||
|
||||
public java.util.Spliterator.OfInt spliterator() {
|
||||
return delegate.spliterator();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import java.util.LongSummaryStatistics;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.PrimitiveIterator.OfLong;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.LongBinaryOperator;
|
||||
import java.util.function.LongConsumer;
|
||||
import java.util.function.LongFunction;
|
||||
import java.util.function.LongPredicate;
|
||||
import java.util.function.LongToDoubleFunction;
|
||||
import java.util.function.LongToIntFunction;
|
||||
import java.util.function.LongUnaryOperator;
|
||||
import java.util.function.ObjLongConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
abstract class DelegatingLongStream implements LongStream {
|
||||
|
||||
private final LongStream delegate;
|
||||
private final DelegatingStreamFactory wrapper;
|
||||
|
||||
public DelegatingLongStream(LongStream delegate, DelegatingStreamFactory wrapper) {
|
||||
this.delegate = delegate;
|
||||
this.wrapper = wrapper;
|
||||
}
|
||||
|
||||
public LongStream filter(LongPredicate predicate) {
|
||||
return wrapper.from(delegate.filter(predicate));
|
||||
}
|
||||
|
||||
public boolean isParallel() {
|
||||
return delegate.isParallel();
|
||||
}
|
||||
|
||||
public LongStream map(LongUnaryOperator mapper) {
|
||||
return wrapper.from(delegate.map(mapper));
|
||||
}
|
||||
|
||||
public <U> Stream<U> mapToObj(LongFunction<? extends U> mapper) {
|
||||
return wrapper.from(delegate.mapToObj(mapper));
|
||||
}
|
||||
|
||||
public LongStream unordered() {
|
||||
return wrapper.from(delegate.unordered());
|
||||
}
|
||||
|
||||
public LongStream onClose(Runnable closeHandler) {
|
||||
return wrapper.from(delegate.onClose(closeHandler));
|
||||
}
|
||||
|
||||
public IntStream mapToInt(LongToIntFunction mapper) {
|
||||
return wrapper.from(delegate.mapToInt(mapper));
|
||||
}
|
||||
|
||||
public DoubleStream mapToDouble(LongToDoubleFunction mapper) {
|
||||
return wrapper.from(delegate.mapToDouble(mapper));
|
||||
}
|
||||
|
||||
public void close() {
|
||||
delegate.close();
|
||||
}
|
||||
|
||||
public LongStream flatMap(LongFunction<? extends LongStream> mapper) {
|
||||
return wrapper.from(delegate.flatMap(mapper));
|
||||
}
|
||||
|
||||
public LongStream distinct() {
|
||||
return wrapper.from(delegate.distinct());
|
||||
}
|
||||
|
||||
public LongStream sorted() {
|
||||
return wrapper.from(delegate.sorted());
|
||||
}
|
||||
|
||||
public LongStream peek(LongConsumer action) {
|
||||
return wrapper.from(delegate.peek(action));
|
||||
}
|
||||
|
||||
public LongStream limit(long maxSize) {
|
||||
return wrapper.from(delegate.limit(maxSize));
|
||||
}
|
||||
|
||||
public LongStream skip(long n) {
|
||||
return wrapper.from(delegate.skip(n));
|
||||
}
|
||||
|
||||
public void forEach(LongConsumer action) {
|
||||
delegate.forEach(action);
|
||||
}
|
||||
|
||||
public void forEachOrdered(LongConsumer action) {
|
||||
delegate.forEachOrdered(action);
|
||||
}
|
||||
|
||||
public long[] toArray() {
|
||||
return delegate.toArray();
|
||||
}
|
||||
|
||||
public long reduce(long identity, LongBinaryOperator op) {
|
||||
return delegate.reduce(identity, op);
|
||||
}
|
||||
|
||||
public OptionalLong reduce(LongBinaryOperator op) {
|
||||
return delegate.reduce(op);
|
||||
}
|
||||
|
||||
public <R> R collect(Supplier<R> supplier, ObjLongConsumer<R> accumulator, BiConsumer<R, R> combiner) {
|
||||
return delegate.collect(supplier, accumulator, combiner);
|
||||
}
|
||||
|
||||
public long sum() {
|
||||
return delegate.sum();
|
||||
}
|
||||
|
||||
public OptionalLong min() {
|
||||
return delegate.min();
|
||||
}
|
||||
|
||||
public OptionalLong max() {
|
||||
return delegate.max();
|
||||
}
|
||||
|
||||
public long count() {
|
||||
return delegate.count();
|
||||
}
|
||||
|
||||
public OptionalDouble average() {
|
||||
return delegate.average();
|
||||
}
|
||||
|
||||
public LongSummaryStatistics summaryStatistics() {
|
||||
return delegate.summaryStatistics();
|
||||
}
|
||||
|
||||
public boolean anyMatch(LongPredicate predicate) {
|
||||
return delegate.anyMatch(predicate);
|
||||
}
|
||||
|
||||
public boolean allMatch(LongPredicate predicate) {
|
||||
return delegate.allMatch(predicate);
|
||||
}
|
||||
|
||||
public boolean noneMatch(LongPredicate predicate) {
|
||||
return delegate.noneMatch(predicate);
|
||||
}
|
||||
|
||||
public OptionalLong findFirst() {
|
||||
return delegate.findFirst();
|
||||
}
|
||||
|
||||
public OptionalLong findAny() {
|
||||
return delegate.findAny();
|
||||
}
|
||||
|
||||
public DoubleStream asDoubleStream() {
|
||||
return wrapper.from(delegate.asDoubleStream());
|
||||
}
|
||||
|
||||
public Stream<Long> boxed() {
|
||||
return wrapper.from(delegate.boxed());
|
||||
}
|
||||
|
||||
public LongStream sequential() {
|
||||
return wrapper.from(delegate.sequential());
|
||||
}
|
||||
|
||||
public LongStream parallel() {
|
||||
return wrapper.from(delegate.parallel());
|
||||
}
|
||||
|
||||
public OfLong iterator() {
|
||||
return delegate.iterator();
|
||||
}
|
||||
|
||||
public java.util.Spliterator.OfLong spliterator() {
|
||||
return delegate.spliterator();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,194 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.Optional;
|
||||
import java.util.Spliterator;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.ToDoubleFunction;
|
||||
import java.util.function.ToIntFunction;
|
||||
import java.util.function.ToLongFunction;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
abstract class DelegatingStream<T> implements Stream<T> {
|
||||
|
||||
private final Stream<T> delegate;
|
||||
private final DelegatingStreamFactory wrapper;
|
||||
|
||||
protected DelegatingStream(Stream<T> delegate, DelegatingStreamFactory wrapper) {
|
||||
this.delegate = delegate;
|
||||
this.wrapper = wrapper;
|
||||
}
|
||||
|
||||
public Iterator<T> iterator() {
|
||||
return delegate.iterator();
|
||||
}
|
||||
|
||||
public Spliterator<T> spliterator() {
|
||||
return delegate.spliterator();
|
||||
}
|
||||
|
||||
public boolean isParallel() {
|
||||
return delegate.isParallel();
|
||||
}
|
||||
|
||||
public Stream<T> sequential() {
|
||||
return wrapper.from(delegate.sequential());
|
||||
}
|
||||
|
||||
public Stream<T> parallel() {
|
||||
return wrapper.from(delegate.parallel());
|
||||
}
|
||||
|
||||
public Stream<T> unordered() {
|
||||
return wrapper.from(delegate.unordered());
|
||||
}
|
||||
|
||||
public Stream<T> onClose(Runnable closeHandler) {
|
||||
return wrapper.from(delegate.onClose(closeHandler));
|
||||
}
|
||||
|
||||
public void close() {
|
||||
delegate.close();
|
||||
}
|
||||
|
||||
public Stream<T> filter(Predicate<? super T> predicate) {
|
||||
return wrapper.from(delegate.filter(predicate));
|
||||
}
|
||||
|
||||
public <R> Stream<R> map(Function<? super T, ? extends R> mapper) {
|
||||
return wrapper.from(delegate.map(mapper));
|
||||
}
|
||||
|
||||
public IntStream mapToInt(ToIntFunction<? super T> mapper) {
|
||||
return wrapper.from(delegate.mapToInt(mapper));
|
||||
}
|
||||
|
||||
public LongStream mapToLong(ToLongFunction<? super T> mapper) {
|
||||
return wrapper.from(delegate.mapToLong(mapper));
|
||||
}
|
||||
|
||||
public DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper) {
|
||||
return wrapper.from(delegate.mapToDouble(mapper));
|
||||
}
|
||||
|
||||
public <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) {
|
||||
return wrapper.from(delegate.flatMap(mapper));
|
||||
}
|
||||
|
||||
public IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper) {
|
||||
return wrapper.from(delegate.flatMapToInt(mapper));
|
||||
}
|
||||
|
||||
public LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper) {
|
||||
return wrapper.from(delegate.flatMapToLong(mapper));
|
||||
}
|
||||
|
||||
public DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper) {
|
||||
return wrapper.from(delegate.flatMapToDouble(mapper));
|
||||
}
|
||||
|
||||
public Stream<T> distinct() {
|
||||
return wrapper.from(delegate.distinct());
|
||||
}
|
||||
|
||||
public Stream<T> sorted() {
|
||||
return wrapper.from(delegate.sorted());
|
||||
}
|
||||
|
||||
public Stream<T> sorted(Comparator<? super T> comparator) {
|
||||
return wrapper.from(delegate.sorted(comparator));
|
||||
}
|
||||
|
||||
public Stream<T> peek(Consumer<? super T> action) {
|
||||
return wrapper.from(delegate.peek(action));
|
||||
}
|
||||
|
||||
public Stream<T> limit(long maxSize) {
|
||||
return wrapper.from(delegate.limit(maxSize));
|
||||
}
|
||||
|
||||
public Stream<T> skip(long n) {
|
||||
return wrapper.from(delegate.skip(n));
|
||||
}
|
||||
|
||||
public void forEach(Consumer<? super T> action) {
|
||||
delegate.forEach(action);
|
||||
}
|
||||
|
||||
public void forEachOrdered(Consumer<? super T> action) {
|
||||
delegate.forEachOrdered(action);
|
||||
}
|
||||
|
||||
public Object[] toArray() {
|
||||
return delegate.toArray();
|
||||
}
|
||||
|
||||
public <A> A[] toArray(IntFunction<A[]> generator) {
|
||||
return delegate.toArray(generator);
|
||||
}
|
||||
|
||||
public T reduce(T identity, BinaryOperator<T> accumulator) {
|
||||
return delegate.reduce(identity, accumulator);
|
||||
}
|
||||
|
||||
public Optional<T> reduce(BinaryOperator<T> accumulator) {
|
||||
return delegate.reduce(accumulator);
|
||||
}
|
||||
|
||||
public <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner) {
|
||||
return delegate.reduce(identity, accumulator, combiner);
|
||||
}
|
||||
|
||||
public <R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner) {
|
||||
return delegate.collect(supplier, accumulator, combiner);
|
||||
}
|
||||
|
||||
public <R, A> R collect(Collector<? super T, A, R> collector) {
|
||||
return delegate.collect(collector);
|
||||
}
|
||||
|
||||
public Optional<T> min(Comparator<? super T> comparator) {
|
||||
return delegate.min(comparator);
|
||||
}
|
||||
|
||||
public Optional<T> max(Comparator<? super T> comparator) {
|
||||
return delegate.max(comparator);
|
||||
}
|
||||
|
||||
public long count() {
|
||||
return delegate.count();
|
||||
}
|
||||
|
||||
public boolean anyMatch(Predicate<? super T> predicate) {
|
||||
return delegate.anyMatch(predicate);
|
||||
}
|
||||
|
||||
public boolean allMatch(Predicate<? super T> predicate) {
|
||||
return delegate.allMatch(predicate);
|
||||
}
|
||||
|
||||
public boolean noneMatch(Predicate<? super T> predicate) {
|
||||
return delegate.noneMatch(predicate);
|
||||
}
|
||||
|
||||
public Optional<T> findFirst() {
|
||||
return delegate.findFirst();
|
||||
}
|
||||
|
||||
public Optional<T> findAny() {
|
||||
return delegate.findAny();
|
||||
}
|
||||
|
||||
}
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public interface DelegatingStreamFactory {
|
||||
|
||||
<S> Stream<S> from(Stream<S> other);
|
||||
|
||||
IntStream from(IntStream other);
|
||||
|
||||
LongStream from(LongStream other);
|
||||
|
||||
DoubleStream from(DoubleStream other);
|
||||
|
||||
public interface ObjectStreamWrapper {
|
||||
<S> Stream<S> from(Stream<S> other);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package org.cryptomator.common;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class CachingSupplierTest {
|
||||
|
||||
@Test
|
||||
public void testInvokingGetInvokesDelegate() {
|
||||
@SuppressWarnings("unchecked")
|
||||
Supplier<Object> delegate = mock(Supplier.class);
|
||||
Object expectedResult = new Object();
|
||||
when(delegate.get()).thenReturn(expectedResult);
|
||||
Supplier<Object> inTest = CachingSupplier.from(delegate);
|
||||
|
||||
Object result = inTest.get();
|
||||
|
||||
assertThat(result, is(expectedResult));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvokingGetTwiceDoesNotInvokeDelegateTwice() {
|
||||
@SuppressWarnings("unchecked")
|
||||
Supplier<Object> delegate = mock(Supplier.class);
|
||||
Object expectedResult = new Object();
|
||||
when(delegate.get()).thenReturn(expectedResult);
|
||||
Supplier<Object> inTest = CachingSupplier.from(delegate);
|
||||
|
||||
inTest.get();
|
||||
Object result = inTest.get();
|
||||
|
||||
assertThat(result, is(expectedResult));
|
||||
verify(delegate).get();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package org.cryptomator.common;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class HolderTest {
|
||||
|
||||
private static final Object INITIAL = new Object();
|
||||
private static final Object VALUE = new Object();
|
||||
|
||||
private Holder<Object> inTest = new Holder<>(INITIAL);
|
||||
|
||||
@Test
|
||||
public void testInitialValueIsInitial() {
|
||||
assertThat(inTest.get(), is(INITIAL));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetChangesValue() {
|
||||
inTest.set(VALUE);
|
||||
|
||||
assertThat(inTest.get(), is(VALUE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptChangesValue() {
|
||||
inTest.accept(VALUE);
|
||||
|
||||
assertThat(inTest.get(), is(VALUE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResetChangesValueToInitial() {
|
||||
inTest.set(VALUE);
|
||||
inTest.reset();
|
||||
|
||||
assertThat(inTest.get(), is(INITIAL));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
package org.cryptomator.common;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
|
||||
public class WeakValuedCacheTest {
|
||||
|
||||
private final String A_KEY = "aKey";
|
||||
private final String ANOTHER_KEY = "anotherKey";
|
||||
|
||||
private WeakValuedCache<String, Value> inTest;
|
||||
|
||||
private Function<String, Value> loader;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Before
|
||||
public void setup() {
|
||||
loader = Mockito.mock(Function.class);
|
||||
inTest = WeakValuedCache.usingLoader(loader);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResultOfGetIsResultOfLoaderForTheSameKey() {
|
||||
Value theValue = new Value();
|
||||
Value theOtherValue = new Value();
|
||||
when(loader.apply(A_KEY)).thenReturn(theValue);
|
||||
when(loader.apply(ANOTHER_KEY)).thenReturn(theOtherValue);
|
||||
|
||||
Value result = inTest.get(A_KEY);
|
||||
Value anotherResult = inTest.get(ANOTHER_KEY);
|
||||
|
||||
assertThat(result, is(sameInstance(theValue)));
|
||||
assertThat(anotherResult, is(sameInstance(theOtherValue)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCachedResultIsResultOfLoaderForTheSameKey() {
|
||||
Value theValue = new Value();
|
||||
Value theOtherValue = new Value();
|
||||
when(loader.apply(A_KEY)).thenReturn(theValue);
|
||||
when(loader.apply(ANOTHER_KEY)).thenReturn(theOtherValue);
|
||||
|
||||
inTest.get(A_KEY);
|
||||
inTest.get(ANOTHER_KEY);
|
||||
Value result = inTest.get(A_KEY);
|
||||
Value anotherResult = inTest.get(ANOTHER_KEY);
|
||||
|
||||
assertThat(result, is(sameInstance(theValue)));
|
||||
assertThat(anotherResult, is(sameInstance(theOtherValue)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwiceInvocationOfGetDoesNotInvokeLoaderTwice() {
|
||||
Value theValue = new Value();
|
||||
when(loader.apply(A_KEY)).thenReturn(theValue);
|
||||
|
||||
inTest.get(A_KEY);
|
||||
inTest.get(A_KEY);
|
||||
|
||||
verify(loader).apply(A_KEY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecondInvocationOfGetReturnsTheSameResult() {
|
||||
Value theValue = new Value();
|
||||
when(loader.apply(A_KEY)).thenReturn(theValue);
|
||||
|
||||
inTest.get(A_KEY);
|
||||
Value result = inTest.get(A_KEY);
|
||||
|
||||
assertThat(result, is(sameInstance(theValue)));
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void testCacheDoesNotPreventGarbageCollectionOfValues() {
|
||||
when(loader.apply(A_KEY)).thenAnswer(this::createValueUsingMoreThanHalfTheJvmMemory);
|
||||
|
||||
inTest.get(A_KEY);
|
||||
|
||||
// force garbage collection of previously created value by creating an
|
||||
// object so large it can not coexist with the value
|
||||
createObjectUsingMoreThanHalfTheJvmMemory();
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeExceptionThrownInLoader.class)
|
||||
public void testCacheRethrowsRuntimeExceptionsFromLoader() {
|
||||
when(loader.apply(A_KEY)).thenThrow(new RuntimeExceptionThrownInLoader());
|
||||
|
||||
inTest.get(A_KEY);
|
||||
}
|
||||
|
||||
@Test(expected = ErrorThrownInLoader.class)
|
||||
public void testCacheRethrowsErrorsFromLoader() {
|
||||
when(loader.apply(A_KEY)).thenThrow(new ErrorThrownInLoader());
|
||||
|
||||
inTest.get(A_KEY);
|
||||
}
|
||||
|
||||
private Value createValueUsingMoreThanHalfTheJvmMemory(InvocationOnMock invocation) {
|
||||
Object data = createObjectUsingMoreThanHalfTheJvmMemory();
|
||||
Value value = new Value();
|
||||
value.setPayload(data);
|
||||
return value;
|
||||
}
|
||||
|
||||
private Object createObjectUsingMoreThanHalfTheJvmMemory() {
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
long moreThanHalfTheJvmMemory = maxMemory / 2 + 1;
|
||||
return createObjectUsingAtLeast(moreThanHalfTheJvmMemory);
|
||||
}
|
||||
|
||||
private Object createObjectUsingAtLeast(long minMemory) {
|
||||
if (minMemory <= Integer.MAX_VALUE) {
|
||||
return new byte[(int) minMemory];
|
||||
} else if ((minMemory / Integer.MAX_VALUE) <= Integer.MAX_VALUE) {
|
||||
int numberOfArraysWithMaxIntSize = (int) (minMemory / Integer.MAX_VALUE);
|
||||
int numberOfRemainingBytes = (int) (minMemory - Integer.MAX_VALUE * numberOfArraysWithMaxIntSize);
|
||||
return new byte[][][] { //
|
||||
new byte[numberOfArraysWithMaxIntSize][Integer.MAX_VALUE], //
|
||||
new byte[1][numberOfRemainingBytes] //
|
||||
};
|
||||
} else {
|
||||
throw new IllegalArgumentException(format("Can not create object with more than 3.999999996 Exabyte"));
|
||||
}
|
||||
}
|
||||
|
||||
private static class RuntimeExceptionThrownInLoader extends RuntimeException {
|
||||
}
|
||||
|
||||
private static class ErrorThrownInLoader extends Error {
|
||||
}
|
||||
|
||||
private static class Value {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private Object payload;
|
||||
|
||||
public void setPayload(Object payload) {
|
||||
this.payload = payload;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+2
-5
@@ -12,10 +12,7 @@ import org.junit.Test;
|
||||
|
||||
public class SettingsJsonAdapterTest {
|
||||
|
||||
private final SettingsJsonAdapter adapter = new SettingsJsonAdapter(this::noop);
|
||||
|
||||
private void noop(Settings settings) {
|
||||
}
|
||||
private final SettingsJsonAdapter adapter = new SettingsJsonAdapter();
|
||||
|
||||
@Test
|
||||
public void testDeserialize() throws IOException {
|
||||
@@ -32,7 +29,7 @@ public class SettingsJsonAdapterTest {
|
||||
Assert.assertTrue(settings.checkForUpdates().get());
|
||||
Assert.assertEquals(2, settings.getDirectories().size());
|
||||
Assert.assertEquals(8080, settings.port().get());
|
||||
Assert.assertTrue(settings.useIpv6().get());
|
||||
// Assert.assertTrue(settings.useIpv6().get()); temporarily ignored
|
||||
Assert.assertEquals(42, settings.numTrayNotifications().get());
|
||||
Assert.assertEquals("dav", settings.preferredGvfsScheme().get());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.cryptomator.common.settings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class SettingsTest {
|
||||
|
||||
@Test
|
||||
public void testAutoSave() throws IOException {
|
||||
@SuppressWarnings("unchecked")
|
||||
Consumer<Settings> changeListener = Mockito.mock(Consumer.class);
|
||||
Settings settings = new Settings();
|
||||
settings.setSaveCmd(changeListener);
|
||||
VaultSettings vaultSettings = VaultSettings.withRandomId();
|
||||
Mockito.verify(changeListener, Mockito.times(0)).accept(settings);
|
||||
|
||||
// first change (to property):
|
||||
settings.preferredGvfsScheme().set("asd");
|
||||
Mockito.verify(changeListener, Mockito.times(1)).accept(settings);
|
||||
|
||||
// second change (to list):
|
||||
settings.getDirectories().add(vaultSettings);
|
||||
Mockito.verify(changeListener, Mockito.times(2)).accept(settings);
|
||||
|
||||
// third change (to property of list item):
|
||||
vaultSettings.mountName().set("asd");
|
||||
Mockito.verify(changeListener, Mockito.times(3)).accept(settings);
|
||||
}
|
||||
|
||||
}
|
||||
+1
-3
@@ -11,7 +11,6 @@ import java.nio.file.Paths;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import com.google.gson.stream.JsonReader;
|
||||
|
||||
@@ -23,9 +22,8 @@ public class VaultSettingsJsonAdapterTest {
|
||||
public void testDeserialize() throws IOException {
|
||||
String json = "{\"id\": \"foo\", \"path\": \"/foo/bar\", \"mountName\": \"test\", \"winDriveLetter\": \"X\", \"shouldBeIgnored\": true}";
|
||||
JsonReader jsonReader = new JsonReader(new StringReader(json));
|
||||
Settings settings = Mockito.mock(Settings.class);
|
||||
|
||||
VaultSettings vaultSettings = adapter.read(jsonReader, settings);
|
||||
VaultSettings vaultSettings = adapter.read(jsonReader);
|
||||
Assert.assertEquals("foo", vaultSettings.getId());
|
||||
Assert.assertEquals(Paths.get("/foo/bar"), vaultSettings.path().get());
|
||||
Assert.assertEquals("test", vaultSettings.mountName().get());
|
||||
|
||||
-227
@@ -1,227 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.anyOf;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.DoubleSummaryStatistics;
|
||||
import java.util.List;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.DoubleBinaryOperator;
|
||||
import java.util.function.DoubleConsumer;
|
||||
import java.util.function.DoubleFunction;
|
||||
import java.util.function.DoublePredicate;
|
||||
import java.util.function.DoubleToIntFunction;
|
||||
import java.util.function.DoubleToLongFunction;
|
||||
import java.util.function.DoubleUnaryOperator;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.ObjDoubleConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.BaseStream;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.experimental.theories.DataPoints;
|
||||
import org.junit.experimental.theories.FromDataPoints;
|
||||
import org.junit.experimental.theories.Theories;
|
||||
import org.junit.experimental.theories.Theory;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@RunWith(Theories.class)
|
||||
public class AutoClosingDoubleStreamTest {
|
||||
|
||||
private static final DoublePredicate A_DOUBLE_PREDICATE = any -> true;
|
||||
private static final DoubleFunction A_DOUBLE_FUNCTION = i -> null;
|
||||
private static final BiConsumer A_BICONSUMER = (a, b) -> {
|
||||
};
|
||||
private static final Supplier A_SUPPLIER = () -> null;
|
||||
|
||||
@DataPoints("intermediateOperations")
|
||||
public static final List<DoubleermediateOperation<?>> INTERMEDIATE_OPERATIONS = new ArrayList<>();
|
||||
|
||||
@DataPoints("terminalOperations")
|
||||
public static final List<TerminalOperation<?>> TERMINAL_OPERATIONS = new ArrayList<>();
|
||||
private static final DoubleUnaryOperator A_DOUBLE_UNARY_OPERATOR = i -> 3;
|
||||
private static final DoubleToLongFunction A_DOUBLE_TO_LONG_FUNCTION = i -> 3L;
|
||||
private static final DoubleToIntFunction A_DOUBLE_TO_INT_FUNCTION = i -> 5;
|
||||
private static final DoubleConsumer A_DOUBLE_CONSUMER = i -> {
|
||||
};
|
||||
private static final ObjDoubleConsumer AN_OBJ_DOUBLE_CONSUMER = (a, b) -> {
|
||||
};
|
||||
private static final DoubleBinaryOperator A_DOUBLE_BINARY_OPERATOR = (a, b) -> a;
|
||||
|
||||
static {
|
||||
// define intermediate operations
|
||||
test(DoubleStream.class, DoubleStream::distinct);
|
||||
test(DoubleStream.class, stream -> stream.filter(A_DOUBLE_PREDICATE));
|
||||
test(DoubleStream.class, stream -> stream.flatMap(A_DOUBLE_FUNCTION));
|
||||
test(DoubleStream.class, stream -> stream.limit(5));
|
||||
test(DoubleStream.class, stream -> stream.map(A_DOUBLE_UNARY_OPERATOR));
|
||||
test(LongStream.class, stream -> stream.mapToLong(A_DOUBLE_TO_LONG_FUNCTION));
|
||||
test(Stream.class, stream -> stream.mapToObj(A_DOUBLE_FUNCTION));
|
||||
test(IntStream.class, stream -> stream.mapToInt(A_DOUBLE_TO_INT_FUNCTION));
|
||||
test(DoubleStream.class, DoubleStream::parallel);
|
||||
test(DoubleStream.class, stream -> stream.peek(A_DOUBLE_CONSUMER));
|
||||
test(DoubleStream.class, DoubleStream::sequential);
|
||||
test(DoubleStream.class, stream -> stream.skip(5));
|
||||
test(DoubleStream.class, DoubleStream::sorted);
|
||||
test(DoubleStream.class, DoubleStream::unordered);
|
||||
test(Stream.class, DoubleStream::boxed);
|
||||
|
||||
// define terminal operations
|
||||
test(stream -> stream.allMatch(A_DOUBLE_PREDICATE), true);
|
||||
test(stream -> stream.anyMatch(A_DOUBLE_PREDICATE), true);
|
||||
test(stream -> stream.collect(A_SUPPLIER, AN_OBJ_DOUBLE_CONSUMER, A_BICONSUMER), 7d);
|
||||
test(DoubleStream::count, 3L);
|
||||
test(DoubleStream::findAny, OptionalDouble.of(3));
|
||||
test(DoubleStream::findFirst, OptionalDouble.of(3));
|
||||
test(stream -> stream.forEach(A_DOUBLE_CONSUMER));
|
||||
test(stream -> stream.forEachOrdered(A_DOUBLE_CONSUMER));
|
||||
test(stream -> stream.max(), OptionalDouble.of(3));
|
||||
test(stream -> stream.min(), OptionalDouble.of(3));
|
||||
test(stream -> stream.noneMatch(A_DOUBLE_PREDICATE), true);
|
||||
test(stream -> stream.reduce(A_DOUBLE_BINARY_OPERATOR), OptionalDouble.of(3));
|
||||
test(stream -> stream.reduce(1, A_DOUBLE_BINARY_OPERATOR), 3d);
|
||||
test(DoubleStream::toArray, new double[1]);
|
||||
test(DoubleStream::sum, 1d);
|
||||
test(DoubleStream::average, OptionalDouble.of(3d));
|
||||
test(DoubleStream::summaryStatistics, new DoubleSummaryStatistics());
|
||||
}
|
||||
|
||||
private static <T> void test(Consumer<DoubleStream> consumer) {
|
||||
TERMINAL_OPERATIONS.add(new TerminalOperation<T>() {
|
||||
@Override
|
||||
public T result() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(DoubleStream stream) {
|
||||
consumer.accept(stream);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <T> void test(Function<DoubleStream, T> function, T result) {
|
||||
TERMINAL_OPERATIONS.add(new TerminalOperation<T>() {
|
||||
@Override
|
||||
public T result() {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(DoubleStream stream) {
|
||||
return function.apply(stream);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <T extends BaseStream> void test(Class<? extends T> type, Function<DoubleStream, T> function) {
|
||||
INTERMEDIATE_OPERATIONS.add(new DoubleermediateOperation<T>() {
|
||||
@Override
|
||||
public Class<? extends T> type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(DoubleStream stream) {
|
||||
return function.apply(stream);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private DoubleStream delegate;
|
||||
private DoubleStream inTest;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
delegate = mock(DoubleStream.class);
|
||||
inTest = AutoClosingDoubleStream.from(delegate);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testIntermediateOperationReturnsNewAutoClosingStream(@FromDataPoints("intermediateOperations") DoubleermediateOperation intermediateOperation) {
|
||||
BaseStream newDelegate = (BaseStream) mock(intermediateOperation.type());
|
||||
when(intermediateOperation.apply(delegate)).thenReturn(newDelegate);
|
||||
|
||||
BaseStream result = intermediateOperation.apply(inTest);
|
||||
|
||||
assertThat(result, isAutoClosing());
|
||||
verifyDelegate(result, newDelegate);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testTerminalOperationDelegatesToAndClosesDelegate(@FromDataPoints("terminalOperations") TerminalOperation terminalOperation) {
|
||||
Object expectedResult = terminalOperation.result();
|
||||
if (expectedResult != null) {
|
||||
when(terminalOperation.apply(delegate)).thenReturn(expectedResult);
|
||||
}
|
||||
|
||||
Object result = terminalOperation.apply(inTest);
|
||||
|
||||
InOrder inOrder = inOrder(delegate);
|
||||
assertThat(result, is(expectedResult));
|
||||
inOrder.verify(delegate).close();
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testTerminalOperationClosesDelegateEvenOnException(@FromDataPoints("terminalOperations") TerminalOperation terminalOperation) {
|
||||
RuntimeException exception = new RuntimeException();
|
||||
terminalOperation.apply(doThrow(exception).when(delegate));
|
||||
|
||||
thrown.expect(is(exception));
|
||||
|
||||
try {
|
||||
terminalOperation.apply(inTest);
|
||||
} finally {
|
||||
verify(delegate).close();
|
||||
}
|
||||
}
|
||||
|
||||
private Matcher<BaseStream> isAutoClosing() {
|
||||
return is(anyOf(instanceOf(AutoClosingStream.class), instanceOf(AutoClosingDoubleStream.class), instanceOf(AutoClosingIntStream.class), instanceOf(AutoClosingLongStream.class)));
|
||||
}
|
||||
|
||||
private void verifyDelegate(BaseStream result, BaseStream newDelegate) {
|
||||
result.close();
|
||||
verify(newDelegate).close();
|
||||
}
|
||||
|
||||
private interface TerminalOperation<T> {
|
||||
|
||||
T result();
|
||||
|
||||
T apply(DoubleStream stream);
|
||||
|
||||
}
|
||||
|
||||
private interface DoubleermediateOperation<T extends BaseStream> {
|
||||
|
||||
Class<? extends T> type();
|
||||
|
||||
T apply(DoubleStream stream);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-228
@@ -1,228 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.anyOf;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.IntSummaryStatistics;
|
||||
import java.util.List;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.IntBinaryOperator;
|
||||
import java.util.function.IntConsumer;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.IntPredicate;
|
||||
import java.util.function.IntToDoubleFunction;
|
||||
import java.util.function.IntToLongFunction;
|
||||
import java.util.function.IntUnaryOperator;
|
||||
import java.util.function.ObjIntConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.BaseStream;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.experimental.theories.DataPoints;
|
||||
import org.junit.experimental.theories.FromDataPoints;
|
||||
import org.junit.experimental.theories.Theories;
|
||||
import org.junit.experimental.theories.Theory;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@RunWith(Theories.class)
|
||||
public class AutoClosingIntStreamTest {
|
||||
|
||||
private static final IntPredicate AN_INT_PREDICATE = any -> true;
|
||||
private static final IntFunction AN_INT_FUNCTION = i -> null;
|
||||
private static final BiConsumer A_BICONSUMER = (a, b) -> {
|
||||
};
|
||||
private static final Supplier A_SUPPLIER = () -> null;
|
||||
|
||||
@DataPoints("intermediateOperations")
|
||||
public static final List<IntermediateOperation<?>> INTERMEDIATE_OPERATIONS = new ArrayList<>();
|
||||
|
||||
@DataPoints("terminalOperations")
|
||||
public static final List<TerminalOperation<?>> TERMINAL_OPERATIONS = new ArrayList<>();
|
||||
private static final IntUnaryOperator AN_INT_UNARY_OPERATOR = i -> 3;
|
||||
private static final IntToDoubleFunction AN_INT_TO_DOUBLE_FUNCTION = i -> 3d;
|
||||
private static final IntToLongFunction AN_INT_TO_LONG_FUNCTION = i -> 5L;
|
||||
private static final IntConsumer AN_INT_CONSUMER = i -> {
|
||||
};
|
||||
private static final ObjIntConsumer AN_OBJ_INT_CONSUMER = (a, b) -> {
|
||||
};
|
||||
private static final IntBinaryOperator AN_INT_BINARY_OPERATOR = (a, b) -> a;
|
||||
|
||||
static {
|
||||
// define intermediate operations
|
||||
test(IntStream.class, IntStream::distinct);
|
||||
test(IntStream.class, stream -> stream.filter(AN_INT_PREDICATE));
|
||||
test(IntStream.class, stream -> stream.flatMap(AN_INT_FUNCTION));
|
||||
test(IntStream.class, stream -> stream.limit(5));
|
||||
test(IntStream.class, stream -> stream.map(AN_INT_UNARY_OPERATOR));
|
||||
test(DoubleStream.class, stream -> stream.mapToDouble(AN_INT_TO_DOUBLE_FUNCTION));
|
||||
test(Stream.class, stream -> stream.mapToObj(AN_INT_FUNCTION));
|
||||
test(LongStream.class, stream -> stream.mapToLong(AN_INT_TO_LONG_FUNCTION));
|
||||
test(IntStream.class, IntStream::parallel);
|
||||
test(IntStream.class, stream -> stream.peek(AN_INT_CONSUMER));
|
||||
test(IntStream.class, IntStream::sequential);
|
||||
test(IntStream.class, stream -> stream.skip(5));
|
||||
test(IntStream.class, IntStream::sorted);
|
||||
test(IntStream.class, IntStream::unordered);
|
||||
test(Stream.class, IntStream::boxed);
|
||||
|
||||
// define terminal operations
|
||||
test(stream -> stream.allMatch(AN_INT_PREDICATE), true);
|
||||
test(stream -> stream.anyMatch(AN_INT_PREDICATE), true);
|
||||
test(stream -> stream.collect(A_SUPPLIER, AN_OBJ_INT_CONSUMER, A_BICONSUMER), 7);
|
||||
test(IntStream::count, 3L);
|
||||
test(IntStream::findAny, OptionalInt.of(3));
|
||||
test(IntStream::findFirst, OptionalInt.of(3));
|
||||
test(stream -> stream.forEach(AN_INT_CONSUMER));
|
||||
test(stream -> stream.forEachOrdered(AN_INT_CONSUMER));
|
||||
test(stream -> stream.max(), OptionalInt.of(3));
|
||||
test(stream -> stream.min(), OptionalInt.of(3));
|
||||
test(stream -> stream.noneMatch(AN_INT_PREDICATE), true);
|
||||
test(stream -> stream.reduce(AN_INT_BINARY_OPERATOR), OptionalInt.of(3));
|
||||
test(stream -> stream.reduce(1, AN_INT_BINARY_OPERATOR), 3);
|
||||
test(IntStream::toArray, new int[1]);
|
||||
test(IntStream::sum, 1);
|
||||
test(IntStream::average, OptionalDouble.of(3d));
|
||||
test(IntStream::summaryStatistics, new IntSummaryStatistics());
|
||||
}
|
||||
|
||||
private static <T> void test(Consumer<IntStream> consumer) {
|
||||
TERMINAL_OPERATIONS.add(new TerminalOperation<T>() {
|
||||
@Override
|
||||
public T result() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(IntStream stream) {
|
||||
consumer.accept(stream);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <T> void test(Function<IntStream, T> function, T result) {
|
||||
TERMINAL_OPERATIONS.add(new TerminalOperation<T>() {
|
||||
@Override
|
||||
public T result() {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(IntStream stream) {
|
||||
return function.apply(stream);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <T extends BaseStream> void test(Class<? extends T> type, Function<IntStream, T> function) {
|
||||
INTERMEDIATE_OPERATIONS.add(new IntermediateOperation<T>() {
|
||||
@Override
|
||||
public Class<? extends T> type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(IntStream stream) {
|
||||
return function.apply(stream);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private IntStream delegate;
|
||||
private IntStream inTest;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
delegate = mock(IntStream.class);
|
||||
inTest = AutoClosingIntStream.from(delegate);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testIntermediateOperationReturnsNewAutoClosingStream(@FromDataPoints("intermediateOperations") IntermediateOperation intermediateOperation) {
|
||||
BaseStream newDelegate = (BaseStream) mock(intermediateOperation.type());
|
||||
when(intermediateOperation.apply(delegate)).thenReturn(newDelegate);
|
||||
|
||||
BaseStream result = intermediateOperation.apply(inTest);
|
||||
|
||||
assertThat(result, isAutoClosing());
|
||||
verifyDelegate(result, newDelegate);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testTerminalOperationDelegatesToAndClosesDelegate(@FromDataPoints("terminalOperations") TerminalOperation terminalOperation) {
|
||||
Object expectedResult = terminalOperation.result();
|
||||
if (expectedResult != null) {
|
||||
when(terminalOperation.apply(delegate)).thenReturn(expectedResult);
|
||||
}
|
||||
|
||||
Object result = terminalOperation.apply(inTest);
|
||||
|
||||
InOrder inOrder = inOrder(delegate);
|
||||
assertThat(result, is(expectedResult));
|
||||
inOrder.verify(delegate).close();
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testTerminalOperationClosesDelegateEvenOnException(@FromDataPoints("terminalOperations") TerminalOperation terminalOperation) {
|
||||
RuntimeException exception = new RuntimeException();
|
||||
terminalOperation.apply(doThrow(exception).when(delegate));
|
||||
|
||||
thrown.expect(is(exception));
|
||||
|
||||
try {
|
||||
terminalOperation.apply(inTest);
|
||||
} finally {
|
||||
verify(delegate).close();
|
||||
}
|
||||
}
|
||||
|
||||
private Matcher<BaseStream> isAutoClosing() {
|
||||
return is(anyOf(instanceOf(AutoClosingStream.class), instanceOf(AutoClosingDoubleStream.class), instanceOf(AutoClosingIntStream.class), instanceOf(AutoClosingLongStream.class)));
|
||||
}
|
||||
|
||||
private void verifyDelegate(BaseStream result, BaseStream newDelegate) {
|
||||
result.close();
|
||||
verify(newDelegate).close();
|
||||
}
|
||||
|
||||
private interface TerminalOperation<T> {
|
||||
|
||||
T result();
|
||||
|
||||
T apply(IntStream stream);
|
||||
|
||||
}
|
||||
|
||||
private interface IntermediateOperation<T extends BaseStream> {
|
||||
|
||||
Class<? extends T> type();
|
||||
|
||||
T apply(IntStream stream);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-228
@@ -1,228 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.anyOf;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.LongSummaryStatistics;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.LongBinaryOperator;
|
||||
import java.util.function.LongConsumer;
|
||||
import java.util.function.LongFunction;
|
||||
import java.util.function.LongPredicate;
|
||||
import java.util.function.LongToDoubleFunction;
|
||||
import java.util.function.LongToIntFunction;
|
||||
import java.util.function.LongUnaryOperator;
|
||||
import java.util.function.ObjLongConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.BaseStream;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.experimental.theories.DataPoints;
|
||||
import org.junit.experimental.theories.FromDataPoints;
|
||||
import org.junit.experimental.theories.Theories;
|
||||
import org.junit.experimental.theories.Theory;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@RunWith(Theories.class)
|
||||
public class AutoClosingLongStreamTest {
|
||||
|
||||
private static final LongPredicate AN_LONG_PREDICATE = any -> true;
|
||||
private static final LongFunction AN_LONG_FUNCTION = i -> null;
|
||||
private static final BiConsumer A_BICONSUMER = (a, b) -> {
|
||||
};
|
||||
private static final Supplier A_SUPPLIER = () -> null;
|
||||
|
||||
@DataPoints("intermediateOperations")
|
||||
public static final List<LongermediateOperation<?>> INTERMEDIATE_OPERATIONS = new ArrayList<>();
|
||||
|
||||
@DataPoints("terminalOperations")
|
||||
public static final List<TerminalOperation<?>> TERMINAL_OPERATIONS = new ArrayList<>();
|
||||
private static final LongUnaryOperator AN_LONG_UNARY_OPERATOR = i -> 3;
|
||||
private static final LongToDoubleFunction AN_LONG_TO_DOUBLE_FUNCTION = i -> 3d;
|
||||
private static final LongToIntFunction AN_LONG_TO_INT_FUNCTION = i -> 5;
|
||||
private static final LongConsumer AN_LONG_CONSUMER = i -> {
|
||||
};
|
||||
private static final ObjLongConsumer AN_OBJ_LONG_CONSUMER = (a, b) -> {
|
||||
};
|
||||
private static final LongBinaryOperator AN_LONG_BINARY_OPERATOR = (a, b) -> a;
|
||||
|
||||
static {
|
||||
// define intermediate operations
|
||||
test(LongStream.class, LongStream::distinct);
|
||||
test(LongStream.class, stream -> stream.filter(AN_LONG_PREDICATE));
|
||||
test(LongStream.class, stream -> stream.flatMap(AN_LONG_FUNCTION));
|
||||
test(LongStream.class, stream -> stream.limit(5));
|
||||
test(LongStream.class, stream -> stream.map(AN_LONG_UNARY_OPERATOR));
|
||||
test(DoubleStream.class, stream -> stream.mapToDouble(AN_LONG_TO_DOUBLE_FUNCTION));
|
||||
test(Stream.class, stream -> stream.mapToObj(AN_LONG_FUNCTION));
|
||||
test(IntStream.class, stream -> stream.mapToInt(AN_LONG_TO_INT_FUNCTION));
|
||||
test(LongStream.class, LongStream::parallel);
|
||||
test(LongStream.class, stream -> stream.peek(AN_LONG_CONSUMER));
|
||||
test(LongStream.class, LongStream::sequential);
|
||||
test(LongStream.class, stream -> stream.skip(5));
|
||||
test(LongStream.class, LongStream::sorted);
|
||||
test(LongStream.class, LongStream::unordered);
|
||||
test(Stream.class, LongStream::boxed);
|
||||
|
||||
// define terminal operations
|
||||
test(stream -> stream.allMatch(AN_LONG_PREDICATE), true);
|
||||
test(stream -> stream.anyMatch(AN_LONG_PREDICATE), true);
|
||||
test(stream -> stream.collect(A_SUPPLIER, AN_OBJ_LONG_CONSUMER, A_BICONSUMER), 7L);
|
||||
test(LongStream::count, 3L);
|
||||
test(LongStream::findAny, OptionalLong.of(3));
|
||||
test(LongStream::findFirst, OptionalLong.of(3));
|
||||
test(stream -> stream.forEach(AN_LONG_CONSUMER));
|
||||
test(stream -> stream.forEachOrdered(AN_LONG_CONSUMER));
|
||||
test(stream -> stream.max(), OptionalLong.of(3));
|
||||
test(stream -> stream.min(), OptionalLong.of(3));
|
||||
test(stream -> stream.noneMatch(AN_LONG_PREDICATE), true);
|
||||
test(stream -> stream.reduce(AN_LONG_BINARY_OPERATOR), OptionalLong.of(3));
|
||||
test(stream -> stream.reduce(1, AN_LONG_BINARY_OPERATOR), 3L);
|
||||
test(LongStream::toArray, new long[1]);
|
||||
test(LongStream::sum, 1L);
|
||||
test(LongStream::average, OptionalDouble.of(3d));
|
||||
test(LongStream::summaryStatistics, new LongSummaryStatistics());
|
||||
}
|
||||
|
||||
private static <T> void test(Consumer<LongStream> consumer) {
|
||||
TERMINAL_OPERATIONS.add(new TerminalOperation<T>() {
|
||||
@Override
|
||||
public T result() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(LongStream stream) {
|
||||
consumer.accept(stream);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <T> void test(Function<LongStream, T> function, T result) {
|
||||
TERMINAL_OPERATIONS.add(new TerminalOperation<T>() {
|
||||
@Override
|
||||
public T result() {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(LongStream stream) {
|
||||
return function.apply(stream);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <T extends BaseStream> void test(Class<? extends T> type, Function<LongStream, T> function) {
|
||||
INTERMEDIATE_OPERATIONS.add(new LongermediateOperation<T>() {
|
||||
@Override
|
||||
public Class<? extends T> type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(LongStream stream) {
|
||||
return function.apply(stream);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private LongStream delegate;
|
||||
private LongStream inTest;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
delegate = mock(LongStream.class);
|
||||
inTest = AutoClosingLongStream.from(delegate);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testIntermediateOperationReturnsNewAutoClosingStream(@FromDataPoints("intermediateOperations") LongermediateOperation intermediateOperation) {
|
||||
BaseStream newDelegate = (BaseStream) mock(intermediateOperation.type());
|
||||
when(intermediateOperation.apply(delegate)).thenReturn(newDelegate);
|
||||
|
||||
BaseStream result = intermediateOperation.apply(inTest);
|
||||
|
||||
assertThat(result, isAutoClosing());
|
||||
verifyDelegate(result, newDelegate);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testTerminalOperationDelegatesToAndClosesDelegate(@FromDataPoints("terminalOperations") TerminalOperation terminalOperation) {
|
||||
Object expectedResult = terminalOperation.result();
|
||||
if (expectedResult != null) {
|
||||
when(terminalOperation.apply(delegate)).thenReturn(expectedResult);
|
||||
}
|
||||
|
||||
Object result = terminalOperation.apply(inTest);
|
||||
|
||||
InOrder inOrder = inOrder(delegate);
|
||||
assertThat(result, is(expectedResult));
|
||||
inOrder.verify(delegate).close();
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testTerminalOperationClosesDelegateEvenOnException(@FromDataPoints("terminalOperations") TerminalOperation terminalOperation) {
|
||||
RuntimeException exception = new RuntimeException();
|
||||
terminalOperation.apply(doThrow(exception).when(delegate));
|
||||
|
||||
thrown.expect(is(exception));
|
||||
|
||||
try {
|
||||
terminalOperation.apply(inTest);
|
||||
} finally {
|
||||
verify(delegate).close();
|
||||
}
|
||||
}
|
||||
|
||||
private Matcher<BaseStream> isAutoClosing() {
|
||||
return is(anyOf(instanceOf(AutoClosingStream.class), instanceOf(AutoClosingDoubleStream.class), instanceOf(AutoClosingIntStream.class), instanceOf(AutoClosingLongStream.class)));
|
||||
}
|
||||
|
||||
private void verifyDelegate(BaseStream result, BaseStream newDelegate) {
|
||||
result.close();
|
||||
verify(newDelegate).close();
|
||||
}
|
||||
|
||||
private interface TerminalOperation<T> {
|
||||
|
||||
T result();
|
||||
|
||||
T apply(LongStream stream);
|
||||
|
||||
}
|
||||
|
||||
private interface LongermediateOperation<T extends BaseStream> {
|
||||
|
||||
Class<? extends T> type();
|
||||
|
||||
T apply(LongStream stream);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.anyOf;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.ToDoubleFunction;
|
||||
import java.util.function.ToIntFunction;
|
||||
import java.util.function.ToLongFunction;
|
||||
import java.util.stream.BaseStream;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.experimental.theories.DataPoints;
|
||||
import org.junit.experimental.theories.FromDataPoints;
|
||||
import org.junit.experimental.theories.Theories;
|
||||
import org.junit.experimental.theories.Theory;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@RunWith(Theories.class)
|
||||
public class AutoClosingStreamTest {
|
||||
|
||||
private static final Predicate A_PREDICATE = any -> true;
|
||||
private static final Function A_FUNCTION = any -> null;
|
||||
private static final ToDoubleFunction A_TO_DOUBLE_FUNCTION = any -> 0d;
|
||||
private static final ToIntFunction A_TO_INT_FUNCTION = any -> 1;
|
||||
private static final ToLongFunction A_TO_LONG_FUNCTION = any -> 1L;
|
||||
private static final Consumer A_CONSUMER = any -> {
|
||||
};
|
||||
private static final Comparator A_COMPARATOR = (left, right) -> 0;
|
||||
private static final Collector A_COLLECTOR = mock(Collector.class);
|
||||
private static final BinaryOperator A_BINARY_OPERATOR = (left, right) -> null;
|
||||
private static final Object AN_OBJECT = new Object();
|
||||
private static final IntFunction AN_INT_FUNCTION = i -> null;
|
||||
private static final BiConsumer A_BICONSUMER = (a, b) -> {
|
||||
};
|
||||
private static final Supplier A_SUPPLIER = () -> null;
|
||||
|
||||
@DataPoints("intermediateOperations")
|
||||
public static final List<IntermediateOperation<?>> INTERMEDIATE_OPERATIONS = new ArrayList<>();
|
||||
|
||||
@DataPoints("terminalOperations")
|
||||
public static final List<TerminalOperation<?>> TERMINAL_OPERATIONS = new ArrayList<>();
|
||||
|
||||
static {
|
||||
// define intermediate operations
|
||||
test(Stream.class, Stream::distinct);
|
||||
test(Stream.class, stream -> stream.filter(A_PREDICATE));
|
||||
test(Stream.class, stream -> stream.flatMap(A_FUNCTION));
|
||||
test(DoubleStream.class, stream -> stream.flatMapToDouble(A_FUNCTION));
|
||||
test(IntStream.class, stream -> stream.flatMapToInt(A_FUNCTION));
|
||||
test(LongStream.class, stream -> stream.flatMapToLong(A_FUNCTION));
|
||||
test(Stream.class, stream -> stream.limit(5));
|
||||
test(Stream.class, stream -> stream.map(A_FUNCTION));
|
||||
test(DoubleStream.class, stream -> stream.mapToDouble(A_TO_DOUBLE_FUNCTION));
|
||||
test(IntStream.class, stream -> stream.mapToInt(A_TO_INT_FUNCTION));
|
||||
test(LongStream.class, stream -> stream.mapToLong(A_TO_LONG_FUNCTION));
|
||||
test(Stream.class, Stream::parallel);
|
||||
test(Stream.class, stream -> stream.peek(A_CONSUMER));
|
||||
test(Stream.class, Stream::sequential);
|
||||
test(Stream.class, stream -> stream.skip(5));
|
||||
test(Stream.class, Stream::sorted);
|
||||
test(Stream.class, stream -> stream.sorted(A_COMPARATOR));
|
||||
test(Stream.class, Stream::unordered);
|
||||
|
||||
// define terminal operations
|
||||
test(stream -> stream.allMatch(A_PREDICATE), true);
|
||||
test(stream -> stream.anyMatch(A_PREDICATE), true);
|
||||
test(stream -> stream.collect(A_COLLECTOR), new Object());
|
||||
test(stream -> stream.collect(A_SUPPLIER, A_BICONSUMER, A_BICONSUMER), new Object());
|
||||
test(Stream::count, 3L);
|
||||
test(Stream::findAny, Optional.of(new Object()));
|
||||
test(Stream::findFirst, Optional.of(new Object()));
|
||||
test(stream -> stream.forEach(A_CONSUMER));
|
||||
test(stream -> stream.forEachOrdered(A_CONSUMER));
|
||||
test(stream -> stream.max(A_COMPARATOR), Optional.of(new Object()));
|
||||
test(stream -> stream.min(A_COMPARATOR), Optional.of(new Object()));
|
||||
test(stream -> stream.noneMatch(A_PREDICATE), true);
|
||||
test(stream -> stream.reduce(A_BINARY_OPERATOR), Optional.of(new Object()));
|
||||
test(stream -> stream.reduce(AN_OBJECT, A_BINARY_OPERATOR), Optional.of(new Object()));
|
||||
test(stream -> stream.reduce(AN_OBJECT, A_BINARY_OPERATOR, A_BINARY_OPERATOR), Optional.of(new Object()));
|
||||
test(Stream::toArray, new Object[1]);
|
||||
test(stream -> stream.toArray(AN_INT_FUNCTION), new Object[1]);
|
||||
}
|
||||
|
||||
private static <T> void test(Consumer<Stream> consumer) {
|
||||
TERMINAL_OPERATIONS.add(new TerminalOperation<T>() {
|
||||
@Override
|
||||
public T result() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(Stream stream) {
|
||||
consumer.accept(stream);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <T> void test(Function<Stream, T> function, T result) {
|
||||
TERMINAL_OPERATIONS.add(new TerminalOperation<T>() {
|
||||
@Override
|
||||
public T result() {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(Stream stream) {
|
||||
return function.apply(stream);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <T extends BaseStream> void test(Class<? extends T> type, Function<Stream, T> function) {
|
||||
INTERMEDIATE_OPERATIONS.add(new IntermediateOperation<T>() {
|
||||
@Override
|
||||
public Class<? extends T> type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(Stream stream) {
|
||||
return function.apply(stream);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private Stream<Object> delegate;
|
||||
private Stream<Object> inTest;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
delegate = mock(Stream.class);
|
||||
inTest = AutoClosingStream.from(delegate);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testIntermediateOperationReturnsNewAutoClosingStream(@FromDataPoints("intermediateOperations") IntermediateOperation intermediateOperation) {
|
||||
BaseStream newDelegate = (BaseStream) mock(intermediateOperation.type());
|
||||
when(intermediateOperation.apply(delegate)).thenReturn(newDelegate);
|
||||
|
||||
BaseStream result = intermediateOperation.apply(inTest);
|
||||
|
||||
assertThat(result, isAutoClosing());
|
||||
verifyDelegate(result, newDelegate);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testTerminalOperationDelegatesToAndClosesDelegate(@FromDataPoints("terminalOperations") TerminalOperation terminalOperation) {
|
||||
Object expectedResult = terminalOperation.result();
|
||||
if (expectedResult != null) {
|
||||
when(terminalOperation.apply(delegate)).thenReturn(expectedResult);
|
||||
}
|
||||
|
||||
Object result = terminalOperation.apply(inTest);
|
||||
|
||||
InOrder inOrder = inOrder(delegate);
|
||||
assertThat(result, is(expectedResult));
|
||||
inOrder.verify(delegate).close();
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testTerminalOperationClosesDelegateEvenOnException(@FromDataPoints("terminalOperations") TerminalOperation terminalOperation) {
|
||||
RuntimeException exception = new RuntimeException();
|
||||
terminalOperation.apply(doThrow(exception).when(delegate));
|
||||
|
||||
thrown.expect(is(exception));
|
||||
|
||||
try {
|
||||
terminalOperation.apply(inTest);
|
||||
} finally {
|
||||
verify(delegate).close();
|
||||
}
|
||||
}
|
||||
|
||||
private Matcher<BaseStream> isAutoClosing() {
|
||||
return is(anyOf(instanceOf(AutoClosingStream.class), instanceOf(AutoClosingDoubleStream.class), instanceOf(AutoClosingIntStream.class), instanceOf(AutoClosingLongStream.class)));
|
||||
}
|
||||
|
||||
private void verifyDelegate(BaseStream result, BaseStream newDelegate) {
|
||||
result.close();
|
||||
verify(newDelegate).close();
|
||||
}
|
||||
|
||||
private interface TerminalOperation<T> {
|
||||
|
||||
T result();
|
||||
|
||||
T apply(Stream stream);
|
||||
|
||||
}
|
||||
|
||||
private interface IntermediateOperation<T extends BaseStream> {
|
||||
|
||||
Class<? extends T> type();
|
||||
|
||||
T apply(Stream stream);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2015 Sebastian Stenzel
|
||||
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
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.2.4</version>
|
||||
</parent>
|
||||
<artifactId>filesystem-charsets</artifactId>
|
||||
<name>Cryptomator filesystem: Charset compatibility layer</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Tests -->
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>commons-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-inmemory</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,64 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2016 Sebastian Stenzel
|
||||
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
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.2.4</version>
|
||||
</parent>
|
||||
<artifactId>filesystem-crypto-integration-tests</artifactId>
|
||||
<name>Cryptomator filesystem: Encryption layer tests</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-crypto</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-nameshortening</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- DI -->
|
||||
<dependency>
|
||||
<groupId>com.google.dagger</groupId>
|
||||
<artifactId>dagger</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.dagger</groupId>
|
||||
<artifactId>dagger-compiler</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Tests -->
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>commons-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-inmemory</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,93 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2015 Sebastian Stenzel
|
||||
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
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.2.4</version>
|
||||
</parent>
|
||||
<artifactId>filesystem-crypto</artifactId>
|
||||
<name>Cryptomator filesystem: Encryption layer</name>
|
||||
|
||||
<properties>
|
||||
<bouncycastle.version>1.51</bouncycastle.version>
|
||||
<sivmode.version>1.2.0</sivmode.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>commons</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Crypto -->
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>siv-mode</artifactId>
|
||||
<version>${sivmode.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<version>${bouncycastle.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Commons -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- JSON -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- DI -->
|
||||
<dependency>
|
||||
<groupId>com.google.dagger</groupId>
|
||||
<artifactId>dagger</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.dagger</groupId>
|
||||
<artifactId>dagger-compiler</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Tests -->
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>commons-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-inmemory</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,41 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2015 Sebastian Stenzel
|
||||
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
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.2.4</version>
|
||||
</parent>
|
||||
<artifactId>filesystem-inmemory</artifactId>
|
||||
<name>Cryptomator filesystem: In-memory mock</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Tests -->
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>commons-test</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,75 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2015 Markus Kreusch
|
||||
This file is licensed under the terms of the MIT license.
|
||||
See the LICENSE.txt file for more info.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.2.4</version>
|
||||
</parent>
|
||||
<artifactId>filesystem-invariants-tests</artifactId>
|
||||
<name>Cryptomator filesystem: Invariants tests</name>
|
||||
<description>Test only project which checks invariants of FileSystem implementations</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-charsets</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-crypto</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-crypto-integration-tests</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-inmemory</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-nameshortening</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-nio</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-stats</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>commons-test</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.dagger</groupId>
|
||||
<artifactId>dagger</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.dagger</groupId>
|
||||
<artifactId>dagger-compiler</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,76 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2015 Sebastian Stenzel
|
||||
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
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.2.4</version>
|
||||
</parent>
|
||||
<artifactId>filesystem-nameshortening</artifactId>
|
||||
<name>Cryptomator filesystem: Name shortening layer</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>commons</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Commons -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- JSON -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- DI -->
|
||||
<dependency>
|
||||
<groupId>com.google.dagger</groupId>
|
||||
<artifactId>dagger</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.dagger</groupId>
|
||||
<artifactId>dagger-compiler</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Tests -->
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>commons-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-inmemory</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,64 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Copyright (c) 2015 Markus Kreusch This file is licensed under the terms
|
||||
of the MIT license. See the LICENSE.txt file for more info. -->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.2.4</version>
|
||||
</parent>
|
||||
<artifactId>filesystem-nio</artifactId>
|
||||
<name>Cryptomator filesystem: NIO-based physical layer</name>
|
||||
<description>FileSystem implementation to access the real file system of an operating system</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>commons</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>commons</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Tests -->
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>commons-test</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,45 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2015 Sebastian Stenzel
|
||||
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
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.2.4</version>
|
||||
</parent>
|
||||
<artifactId>filesystem-stats</artifactId>
|
||||
<name>Cryptomator filesystem: Throughput statistics</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Tests -->
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>commons-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-inmemory</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,27 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2016 Sebastian Stenzel
|
||||
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
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.2.4</version>
|
||||
</parent>
|
||||
<artifactId>frontend-api</artifactId>
|
||||
<name>Cryptomator frontend: API</name>
|
||||
<description>API for filesystem frontends</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -1,134 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2015 Sebastian Stenzel
|
||||
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
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.2.4</version>
|
||||
</parent>
|
||||
<artifactId>frontend-webdav</artifactId>
|
||||
<name>Cryptomator frontend: WebDAV frontend</name>
|
||||
<description>Provides access via WebDAV to filesystems</description>
|
||||
|
||||
<properties>
|
||||
<jackrabbit.version>2.11.3</jackrabbit.version>
|
||||
<jetty.version>9.3.3.v20150827</jetty.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>commons</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>frontend-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Jackrabbit -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.jackrabbit</groupId>
|
||||
<artifactId>jackrabbit-webdav</artifactId>
|
||||
<version>${jackrabbit.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Jetty -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-webapp</artifactId>
|
||||
<version>${jetty.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Guava -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Commons -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- DI -->
|
||||
<dependency>
|
||||
<groupId>com.google.dagger</groupId>
|
||||
<artifactId>dagger</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.dagger</groupId>
|
||||
<artifactId>dagger-compiler</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Test -->
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>commons-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-inmemory</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-crypto-integration-tests</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-nameshortening</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-crypto</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-httpclient</groupId>
|
||||
<artifactId>commons-httpclient</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>filesystem-nio</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -5,12 +5,53 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.3.0-rc1</version>
|
||||
<version>1.3.0-rc4</version>
|
||||
</parent>
|
||||
<artifactId>jacoco-report</artifactId>
|
||||
<name>Cryptomator Code Coverage Report</name>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<dependencies>
|
||||
<!-- all modules containing unit tests: -->
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>commons</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>keychain</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>ui</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>launcher</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<!-- conflict with codacy-coverage-reporter -->
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- binary dependency used during build -->
|
||||
<dependency>
|
||||
<groupId>com.codacy</groupId>
|
||||
<artifactId>codacy-coverage-reporter</artifactId>
|
||||
<version>1.0.13</version>
|
||||
<classifier>assembly</classifier>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>*</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
@@ -26,6 +67,28 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.5.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>java</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<mainClass>com.codacy.CodacyCoverageReporter</mainClass>
|
||||
<arguments>
|
||||
<argument>-l</argument>
|
||||
<argument>Java</argument>
|
||||
<argument>-r</argument>
|
||||
<argument>${project.build.directory}/site/jacoco-aggregate/jacoco.xml</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.3.0-rc1</version>
|
||||
<version>1.3.0-rc4</version>
|
||||
</parent>
|
||||
<artifactId>keychain</artifactId>
|
||||
<name>System Keychain Access</name>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.3.0-rc1</version>
|
||||
<version>1.3.0-rc4</version>
|
||||
</parent>
|
||||
<artifactId>launcher</artifactId>
|
||||
<name>Cryptomator Launcher</name>
|
||||
|
||||
@@ -17,7 +17,7 @@ public class Cryptomator {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Cryptomator.class);
|
||||
static final BlockingQueue<Path> FILE_OPEN_REQUESTS = new ArrayBlockingQueue<>(10);
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
public static void main(String[] args) {
|
||||
LOG.info("Starting Cryptomator {} on {} {} ({})", ApplicationVersion.orElse("SNAPSHOT"), SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH);
|
||||
|
||||
FileOpenRequestHandler fileOpenRequestHandler = new FileOpenRequestHandler(FILE_OPEN_REQUESTS);
|
||||
@@ -30,6 +30,8 @@ public class Cryptomator {
|
||||
communicator.handleLaunchArgs(args);
|
||||
LOG.info("Found running application instance. Shutting down.");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.error("Failed to initiate inter-process communication.", e);
|
||||
}
|
||||
System.exit(0); // end remaining non-daemon threads.
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.rmi.ConnectException;
|
||||
import java.rmi.NoSuchObjectException;
|
||||
import java.rmi.NotBoundException;
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
@@ -27,6 +26,8 @@ import org.apache.commons.lang3.SystemUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.io.MoreFiles;
|
||||
|
||||
/**
|
||||
* First running application on a machine opens a server socket. Further processes will connect as clients.
|
||||
*/
|
||||
@@ -113,7 +114,7 @@ abstract class InterProcessCommunicator implements InterProcessCommunicationProt
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
public void close() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@@ -150,14 +151,14 @@ abstract class InterProcessCommunicator implements InterProcessCommunicationProt
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
public void close() {
|
||||
try {
|
||||
registry.unbind(RMI_NAME);
|
||||
UnicastRemoteObject.unexportObject(remote, true);
|
||||
socket.close();
|
||||
LOG.debug("Server shut down.");
|
||||
} catch (NotBoundException | NoSuchObjectException e) {
|
||||
// ignore
|
||||
} catch (NotBoundException | IOException e) {
|
||||
LOG.warn("Failed to close IPC Server.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,6 +223,7 @@ abstract class InterProcessCommunicator implements InterProcessCommunicationProt
|
||||
ByteBuffer buf = ByteBuffer.allocate(Integer.BYTES);
|
||||
buf.putInt(port);
|
||||
buf.flip();
|
||||
MoreFiles.createParentDirectories(path);
|
||||
try (WritableByteChannel ch = Files.newByteChannel(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
|
||||
if (ch.write(buf) != Integer.BYTES) {
|
||||
throw new IOException("Did not write expected number of bytes.");
|
||||
|
||||
+13
@@ -6,6 +6,7 @@ import java.nio.channels.SeekableByteChannel;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.nio.file.spi.FileSystemProvider;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@@ -17,6 +18,8 @@ import org.mockito.Mockito;
|
||||
public class InterProcessCommunicatorTest {
|
||||
|
||||
Path portFilePath = Mockito.mock(Path.class);
|
||||
Path portFileParentPath = Mockito.mock(Path.class);
|
||||
BasicFileAttributes portFileParentPathAttrs = Mockito.mock(BasicFileAttributes.class);
|
||||
FileSystem fs = Mockito.mock(FileSystem.class);
|
||||
FileSystemProvider provider = Mockito.mock(FileSystemProvider.class);
|
||||
SeekableByteChannel portFileChannel = Mockito.mock(SeekableByteChannel.class);
|
||||
@@ -25,7 +28,13 @@ public class InterProcessCommunicatorTest {
|
||||
@Before
|
||||
public void setup() throws IOException {
|
||||
Mockito.when(portFilePath.getFileSystem()).thenReturn(fs);
|
||||
Mockito.when(portFilePath.toAbsolutePath()).thenReturn(portFilePath);
|
||||
Mockito.when(portFilePath.normalize()).thenReturn(portFilePath);
|
||||
Mockito.when(portFilePath.getParent()).thenReturn(portFileParentPath);
|
||||
Mockito.when(portFileParentPath.getFileSystem()).thenReturn(fs);
|
||||
Mockito.when(fs.provider()).thenReturn(provider);
|
||||
Mockito.when(provider.readAttributes(portFileParentPath, BasicFileAttributes.class)).thenReturn(portFileParentPathAttrs);
|
||||
Mockito.when(portFileParentPathAttrs.isDirectory()).thenReturn(false, true); // Guava's MoreFiles will check if dir exists before attempting to create them.
|
||||
Mockito.when(provider.newByteChannel(Mockito.eq(portFilePath), Mockito.any(), Mockito.any())).thenReturn(portFileChannel);
|
||||
Mockito.when(portFileChannel.read(Mockito.any())).then(invocation -> {
|
||||
ByteBuffer buf = invocation.getArgument(0);
|
||||
@@ -45,6 +54,7 @@ public class InterProcessCommunicatorTest {
|
||||
InterProcessCommunicationProtocol protocol = Mockito.mock(InterProcessCommunicationProtocol.class);
|
||||
try (InterProcessCommunicator result = InterProcessCommunicator.start(portFilePath, protocol)) {
|
||||
Assert.assertTrue(result.isServer());
|
||||
Mockito.verify(provider).createDirectory(portFileParentPath);
|
||||
Mockito.verifyZeroInteractions(protocol);
|
||||
result.handleLaunchArgs(new String[] {"foo"});
|
||||
}
|
||||
@@ -57,6 +67,7 @@ public class InterProcessCommunicatorTest {
|
||||
InterProcessCommunicationProtocol protocol = Mockito.mock(InterProcessCommunicationProtocol.class);
|
||||
try (InterProcessCommunicator result = InterProcessCommunicator.start(portFilePath, protocol)) {
|
||||
Assert.assertTrue(result.isServer());
|
||||
Mockito.verify(provider).createDirectory(portFileParentPath);
|
||||
Mockito.verifyZeroInteractions(protocol);
|
||||
}
|
||||
}
|
||||
@@ -67,10 +78,12 @@ public class InterProcessCommunicatorTest {
|
||||
InterProcessCommunicationProtocol protocol = Mockito.mock(InterProcessCommunicationProtocol.class);
|
||||
try (InterProcessCommunicator result1 = InterProcessCommunicator.start(portFilePath, protocol)) {
|
||||
Assert.assertTrue(result1.isServer());
|
||||
Mockito.verify(provider, Mockito.times(1)).createDirectory(portFileParentPath);
|
||||
Mockito.verifyZeroInteractions(protocol);
|
||||
|
||||
try (InterProcessCommunicator result2 = InterProcessCommunicator.start(portFilePath, null)) {
|
||||
Assert.assertFalse(result2.isServer());
|
||||
Mockito.verify(provider, Mockito.times(1)).createDirectory(portFileParentPath);
|
||||
Assert.assertNotSame(result1, result2);
|
||||
|
||||
result2.handleLaunchArgs(new String[] {"foo"});
|
||||
|
||||
+14
-5
@@ -6,7 +6,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.3.0-rc1</version>
|
||||
<version>1.3.0-rc4</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Cryptomator</name>
|
||||
|
||||
@@ -28,9 +28,9 @@
|
||||
|
||||
<!-- dependency versions -->
|
||||
<cryptomator.cryptolib.version>1.1.1</cryptomator.cryptolib.version>
|
||||
<cryptomator.cryptofs.version>1.2.0</cryptomator.cryptofs.version>
|
||||
<cryptomator.webdav.version>0.4.0</cryptomator.webdav.version>
|
||||
<cryptomator.jni.version>1.0.0</cryptomator.jni.version>
|
||||
<cryptomator.cryptofs.version>1.2.2</cryptomator.cryptofs.version>
|
||||
<cryptomator.webdav.version>0.6.0</cryptomator.webdav.version>
|
||||
<cryptomator.jni.version>1.0.2</cryptomator.jni.version>
|
||||
<log4j.version>2.8.1</log4j.version> <!-- keep in sync with https://github.com/edwgiz/maven-shaded-log4j-transformer (used in uber-jar), or wait for https://issues.apache.org/jira/browse/LOG4J2-954 fix -->
|
||||
<slf4j.version>1.7.25</slf4j.version>
|
||||
<junit.version>4.12</junit.version>
|
||||
@@ -239,6 +239,7 @@
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-all</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
@@ -268,10 +269,18 @@
|
||||
</modules>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>test-coverage</id>
|
||||
<id>coverage</id>
|
||||
<modules>
|
||||
<module>jacoco-report</module>
|
||||
</modules>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.3.0-rc1</version>
|
||||
<version>1.3.0-rc4</version>
|
||||
</parent>
|
||||
<artifactId>uber-jar</artifactId>
|
||||
<name>Single über jar with all dependencies</name>
|
||||
|
||||
+4
-11
@@ -12,7 +12,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.3.0-rc1</version>
|
||||
<version>1.3.0-rc4</version>
|
||||
</parent>
|
||||
<artifactId>ui</artifactId>
|
||||
<name>Cryptomator GUI</name>
|
||||
@@ -99,16 +99,9 @@
|
||||
|
||||
<!-- Logging -->
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-jul</artifactId>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -62,15 +62,7 @@ public class ExitUtil {
|
||||
this.macFunctions = macFunctions;
|
||||
}
|
||||
|
||||
public void initExitHandler() {
|
||||
initExitHandler(ExitUtil::platformExitOnMainThread);
|
||||
}
|
||||
|
||||
private static void platformExitOnMainThread() {
|
||||
Platform.runLater(Platform::exit);
|
||||
}
|
||||
|
||||
private void initExitHandler(Runnable exitCommand) {
|
||||
public void initExitHandler(Runnable exitCommand) {
|
||||
if (SystemUtils.IS_OS_LINUX) {
|
||||
initMinimizeExitHandler(exitCommand);
|
||||
} else {
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
@@ -26,16 +26,16 @@ import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
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;
|
||||
@@ -51,6 +51,8 @@ import javafx.beans.binding.BooleanBinding;
|
||||
import javafx.beans.binding.BooleanExpression;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Side;
|
||||
@@ -83,11 +85,11 @@ public class MainController implements ViewController {
|
||||
private final Localization localization;
|
||||
private final ExecutorService executorService;
|
||||
private final BlockingQueue<Path> fileOpenRequests;
|
||||
private final Settings settings;
|
||||
private final VaultFactory vaultFactoy;
|
||||
private final ViewControllerLoader viewControllerLoader;
|
||||
private final ObjectProperty<ViewController> activeController = new SimpleObjectProperty<>();
|
||||
private final VaultList vaults;
|
||||
private final ObservableList<Vault> vaults;
|
||||
private final BooleanBinding areAllVaultsLocked;
|
||||
private final ObjectProperty<Vault> selectedVault = new SimpleObjectProperty<>();
|
||||
private final BooleanExpression isSelectedVaultUnlocked = BooleanExpression.booleanExpression(EasyBind.select(selectedVault).selectObject(Vault::unlockedProperty).orElse(false));
|
||||
private final BooleanExpression isSelectedVaultValid = BooleanExpression.booleanExpression(EasyBind.monadic(selectedVault).map(Vault::isValidVaultDirectory).orElse(false));
|
||||
@@ -100,13 +102,12 @@ public class MainController implements ViewController {
|
||||
|
||||
@Inject
|
||||
public MainController(@Named("mainWindow") Stage mainWindow, ExecutorService executorService, @Named("fileOpenRequests") BlockingQueue<Path> fileOpenRequests, ExitUtil exitUtil, Localization localization,
|
||||
Settings settings, VaultFactory vaultFactoy, ViewControllerLoader viewControllerLoader, UpgradeStrategies upgradeStrategies, VaultList vaults) {
|
||||
VaultFactory vaultFactoy, ViewControllerLoader viewControllerLoader, UpgradeStrategies upgradeStrategies, VaultList vaults, AutoUnlocker autoUnlocker) {
|
||||
this.mainWindow = mainWindow;
|
||||
this.executorService = executorService;
|
||||
this.fileOpenRequests = fileOpenRequests;
|
||||
this.exitUtil = exitUtil;
|
||||
this.localization = localization;
|
||||
this.settings = settings;
|
||||
this.vaultFactoy = vaultFactoy;
|
||||
this.viewControllerLoader = viewControllerLoader;
|
||||
this.vaults = vaults;
|
||||
@@ -114,6 +115,10 @@ public class MainController implements ViewController {
|
||||
// derived bindings:
|
||||
this.isShowingSettings = Bindings.equal(SettingsController.class, EasyBind.monadic(activeController).map(ViewController::getClass));
|
||||
this.upgradeStrategyForSelectedVault = EasyBind.monadic(selectedVault).map(upgradeStrategies::getUpgradeStrategy);
|
||||
this.areAllVaultsLocked = Bindings.isEmpty(FXCollections.observableList(vaults, Vault::observables).filtered(Vault::isUnlocked));
|
||||
|
||||
EasyBind.subscribe(areAllVaultsLocked, Platform::setImplicitExit);
|
||||
autoUnlocker.unlockAllSilently();
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -184,10 +189,15 @@ public class MainController implements ViewController {
|
||||
stage.getIcons().add(new Image(getClass().getResourceAsStream("/window_icon.png")));
|
||||
Application.setUserAgentStylesheet(getClass().getResource("/css/win_theme.css").toString());
|
||||
}
|
||||
exitUtil.initExitHandler();
|
||||
exitUtil.initExitHandler(this::gracefulShutdown);
|
||||
listenToFileOpenRequests(stage);
|
||||
}
|
||||
|
||||
private void gracefulShutdown() {
|
||||
vaults.filtered(Vault::isUnlocked).forEach(Vault::prepareForShutdown);
|
||||
Platform.runLater(Platform::exit);
|
||||
}
|
||||
|
||||
private void loadFont(String resourcePath) {
|
||||
try (InputStream in = getClass().getResourceAsStream(resourcePath)) {
|
||||
Font.loadFont(in, 12.0);
|
||||
@@ -259,7 +269,7 @@ public class MainController implements ViewController {
|
||||
final List<File> files = fileChooser.showOpenMultipleDialog(mainWindow);
|
||||
if (files != null) {
|
||||
for (final File file : files) {
|
||||
addVault(file.toPath(), false);
|
||||
addVault(file.toPath(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -281,7 +291,7 @@ public class MainController implements ViewController {
|
||||
}
|
||||
|
||||
final Vault vault = vaults.stream().filter(v -> v.getPath().equals(vaultPath)).findAny().orElseGet(() -> {
|
||||
VaultSettings vaultSettings = VaultSettings.withRandomId(settings);
|
||||
VaultSettings vaultSettings = VaultSettings.withRandomId();
|
||||
vaultSettings.path().set(vaultPath);
|
||||
return vaultFactoy.get(vaultSettings);
|
||||
});
|
||||
@@ -399,7 +409,6 @@ public class MainController implements ViewController {
|
||||
}
|
||||
|
||||
public void didUnlock(Vault vault) {
|
||||
Platform.setImplicitExit(false);
|
||||
if (vault.equals(selectedVault.getValue())) {
|
||||
this.showUnlockedView(vault);
|
||||
}
|
||||
@@ -417,9 +426,6 @@ public class MainController implements ViewController {
|
||||
public void didLock(UnlockedController ctrl) {
|
||||
unlockedVaults.remove(ctrl.getVault());
|
||||
showUnlockView();
|
||||
if (!vaults.stream().anyMatch(Vault::isUnlocked)) {
|
||||
Platform.setImplicitExit(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void showChangePasswordView() {
|
||||
|
||||
@@ -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,10 +14,12 @@ import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.commons.lang3.CharUtils;
|
||||
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;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.event.ActionEvent;
|
||||
@@ -34,6 +36,8 @@ import javafx.scene.layout.VBox;
|
||||
@Singleton
|
||||
public class SettingsController implements ViewController {
|
||||
|
||||
private static final CharMatcher DIGITS_MATCHER = CharMatcher.inRange('0', '9');
|
||||
|
||||
private final Localization localization;
|
||||
private final Settings settings;
|
||||
private final Optional<String> applicationVersion;
|
||||
@@ -130,11 +134,7 @@ public class SettingsController implements ViewController {
|
||||
}
|
||||
|
||||
private void filterNumericKeyEvents(KeyEvent t) {
|
||||
if (t.getCharacter() == null || t.getCharacter().length() == 0) {
|
||||
return;
|
||||
}
|
||||
char c = CharUtils.toChar(t.getCharacter());
|
||||
if (!(CharUtils.isAsciiNumeric(c) || c == '_')) {
|
||||
if (!Strings.isNullOrEmpty(t.getCharacter()) && !DIGITS_MATCHER.matchesAllOf(t.getCharacter())) {
|
||||
t.consume();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
@@ -17,20 +17,26 @@ import javax.inject.Inject;
|
||||
|
||||
import org.apache.commons.lang3.CharUtils;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
|
||||
import org.cryptomator.cryptolib.api.UnsupportedVaultFormatException;
|
||||
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;
|
||||
import org.fxmisc.easybind.Subscription;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
@@ -55,6 +61,11 @@ import javafx.util.StringConverter;
|
||||
public class UnlockController implements ViewController {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(UnlockController.class);
|
||||
private static final CharMatcher ALPHA_NUMERIC_MATCHER = CharMatcher.inRange('a', 'z') //
|
||||
.or(CharMatcher.inRange('A', 'Z')) //
|
||||
.or(CharMatcher.inRange('0', '9')) //
|
||||
.or(CharMatcher.is('_')) //
|
||||
.precomputed();
|
||||
|
||||
private final Application app;
|
||||
private final Localization localization;
|
||||
@@ -64,6 +75,7 @@ public class UnlockController implements ViewController {
|
||||
private final Optional<KeychainAccess> keychainAccess;
|
||||
private Vault vault;
|
||||
private Optional<UnlockListener> listener = Optional.empty();
|
||||
private Subscription vaultSubs = Subscription.EMPTY;
|
||||
|
||||
@Inject
|
||||
public UnlockController(Application app, Localization localization, AsyncTaskService asyncTaskService, WindowsDriveLetters driveLetters, Optional<KeychainAccess> keychainAccess) {
|
||||
@@ -116,6 +128,9 @@ public class UnlockController implements ViewController {
|
||||
@FXML
|
||||
private GridPane root;
|
||||
|
||||
@FXML
|
||||
private CheckBox unlockAfterStartup;
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
advancedOptions.managedProperty().bind(advancedOptions.visibleProperty());
|
||||
@@ -125,6 +140,7 @@ public class UnlockController implements ViewController {
|
||||
mountName.addEventFilter(KeyEvent.KEY_TYPED, this::filterAlphanumericKeyEvents);
|
||||
mountName.textProperty().addListener(this::mountNameDidChange);
|
||||
savePassword.setDisable(!keychainAccess.isPresent());
|
||||
unlockAfterStartup.disableProperty().bind(savePassword.disabledProperty().or(savePassword.selectedProperty().not()));
|
||||
if (SystemUtils.IS_OS_WINDOWS) {
|
||||
winDriveLetter.setConverter(new WinDriveLetterLabelConverter());
|
||||
} else {
|
||||
@@ -141,18 +157,17 @@ public class UnlockController implements ViewController {
|
||||
}
|
||||
|
||||
void setVault(Vault vault) {
|
||||
// TODO overheadhunter refactor
|
||||
if (this.vault != null) {
|
||||
this.vault.getVaultSettings().mountAfterUnlock().unbind();
|
||||
this.vault.getVaultSettings().revealAfterMount().unbind();
|
||||
}
|
||||
vaultSubs.unsubscribe();
|
||||
vaultSubs = Subscription.EMPTY;
|
||||
|
||||
// trigger "default" change to refresh key bindings:
|
||||
unlockButton.setDefaultButton(false);
|
||||
unlockButton.setDefaultButton(true);
|
||||
if (vault.equals(this.vault)) {
|
||||
if (Objects.equals(this.vault, Objects.requireNonNull(vault))) {
|
||||
return;
|
||||
}
|
||||
this.vault = Objects.requireNonNull(vault);
|
||||
assert vault != null;
|
||||
this.vault = vault;
|
||||
passwordField.swipe();
|
||||
advancedOptions.setVisible(false);
|
||||
advancedOptionsButton.setText(localization.getString("unlock.button.advancedOptions.show"));
|
||||
@@ -182,10 +197,14 @@ public class UnlockController implements ViewController {
|
||||
Arrays.fill(storedPw, ' ');
|
||||
}
|
||||
}
|
||||
mountAfterUnlock.setSelected(this.vault.getVaultSettings().mountAfterUnlock().get());
|
||||
revealAfterMount.setSelected(this.vault.getVaultSettings().revealAfterMount().get());
|
||||
this.vault.getVaultSettings().mountAfterUnlock().bind(mountAfterUnlock.selectedProperty());
|
||||
this.vault.getVaultSettings().revealAfterMount().bind(revealAfterMount.selectedProperty());
|
||||
VaultSettings settings = vault.getVaultSettings();
|
||||
unlockAfterStartup.setSelected(savePassword.isSelected() && settings.unlockAfterStartup().get());
|
||||
mountAfterUnlock.setSelected(settings.mountAfterUnlock().get());
|
||||
revealAfterMount.setSelected(settings.revealAfterMount().get());
|
||||
|
||||
vaultSubs = vaultSubs.and(EasyBind.subscribe(unlockAfterStartup.selectedProperty(), settings.unlockAfterStartup()::set));
|
||||
vaultSubs = vaultSubs.and(EasyBind.subscribe(mountAfterUnlock.selectedProperty(), settings.mountAfterUnlock()::set));
|
||||
vaultSubs = vaultSubs.and(EasyBind.subscribe(revealAfterMount.selectedProperty(), settings.revealAfterMount()::set));
|
||||
}
|
||||
|
||||
// ****************************************
|
||||
@@ -212,11 +231,7 @@ public class UnlockController implements ViewController {
|
||||
}
|
||||
|
||||
private void filterAlphanumericKeyEvents(KeyEvent t) {
|
||||
if (t.getCharacter() == null || t.getCharacter().length() == 0) {
|
||||
return;
|
||||
}
|
||||
char c = CharUtils.toChar(t.getCharacter());
|
||||
if (!(CharUtils.isAsciiAlphanumeric(c) || c == '_')) {
|
||||
if (!Strings.isNullOrEmpty(t.getCharacter()) && !ALPHA_NUMERIC_MATCHER.matchesAllOf(t.getCharacter())) {
|
||||
t.consume();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
@@ -8,14 +8,19 @@
|
||||
******************************************************************************/
|
||||
package org.cryptomator.ui.controllers;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
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;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javafx.animation.Animation;
|
||||
import javafx.animation.KeyFrame;
|
||||
@@ -31,6 +36,8 @@ import javafx.scene.chart.LineChart;
|
||||
import javafx.scene.chart.NumberAxis;
|
||||
import javafx.scene.chart.XYChart.Data;
|
||||
import javafx.scene.chart.XYChart.Series;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.control.ContextMenu;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.MenuItem;
|
||||
@@ -43,6 +50,8 @@ import javafx.util.Duration;
|
||||
|
||||
public class UnlockedController implements ViewController {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(UnlockedController.class);
|
||||
|
||||
private static final int IO_SAMPLING_STEPS = 100;
|
||||
private static final double IO_SAMPLING_INTERVAL = 0.25;
|
||||
|
||||
@@ -109,16 +118,63 @@ public class UnlockedController implements ViewController {
|
||||
|
||||
@FXML
|
||||
private void didClickLockVault(ActionEvent event) {
|
||||
regularLockVault();
|
||||
}
|
||||
|
||||
private void regularLockVault() {
|
||||
asyncTaskService.asyncTaskOf(() -> {
|
||||
vault.get().unmount();
|
||||
vault.get().lock();
|
||||
}).onSuccess(() -> {
|
||||
listener.ifPresent(listener -> listener.didLock(this));
|
||||
}).onError(Exception.class, () -> {
|
||||
messageLabel.setText(localization.getString("unlocked.label.unmountFailed"));
|
||||
LOG.trace("Regular lock succeeded");
|
||||
}).onError(Exception.class, e -> {
|
||||
onRegularLockVaultFailed(e);
|
||||
}).run();
|
||||
}
|
||||
|
||||
private void forcedLockVault() {
|
||||
asyncTaskService.asyncTaskOf(() -> {
|
||||
vault.get().unmountForced();
|
||||
vault.get().lock();
|
||||
}).onSuccess(() -> {
|
||||
listener.ifPresent(listener -> listener.didLock(this));
|
||||
LOG.trace("Forced lock succeeded");
|
||||
}).onError(Exception.class, e -> {
|
||||
onForcedLockVaultFailed(e);
|
||||
}).run();
|
||||
}
|
||||
|
||||
private void onRegularLockVaultFailed(Exception e) {
|
||||
if (vault.get().supportsForcedUnmount()) {
|
||||
LOG.trace("Regular unmount failed", e);
|
||||
Alert confirmDialog = DialogBuilderUtil.buildYesNoDialog( //
|
||||
format(localization.getString("unlocked.lock.force.confirmation.title"), vault.get().name().getValue()), //
|
||||
localization.getString("unlocked.lock.force.confirmation.header"), //
|
||||
localization.getString("unlocked.lock.force.confirmation.content"), //
|
||||
ButtonType.NO);
|
||||
|
||||
Optional<ButtonType> choice = confirmDialog.showAndWait();
|
||||
if (ButtonType.YES.equals(choice.get())) {
|
||||
forcedLockVault();
|
||||
} else {
|
||||
LOG.trace("Unmount cancelled", e);
|
||||
}
|
||||
} else {
|
||||
LOG.error("Regular unmount failed", e);
|
||||
showUnmountFailedMessage();
|
||||
}
|
||||
}
|
||||
|
||||
private void onForcedLockVaultFailed(Exception e) {
|
||||
LOG.error("Forced unmount failed", e);
|
||||
showUnmountFailedMessage();
|
||||
}
|
||||
|
||||
private void showUnmountFailedMessage() {
|
||||
messageLabel.setText(localization.getString("unlocked.label.unmountFailed"));
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void didClickMoreOptions(ActionEvent event) {
|
||||
if (moreOptionsMenu.isShowing()) {
|
||||
|
||||
@@ -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;
|
||||
@@ -119,10 +119,11 @@ public class WelcomeController implements ViewController {
|
||||
.setConnectionRequestTimeout(5000) //
|
||||
.setSocketTimeout(5000) //
|
||||
.build();
|
||||
String userAgent = String.format("Cryptomator VersionChecker/%s %s %s (%s)", applicationVersion.orElse("SNAPSHOT"), SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH);
|
||||
HttpClientBuilder httpClientBuilder = HttpClients.custom() //
|
||||
.disableCookieManagement() //
|
||||
.setDefaultRequestConfig(requestConfig) //
|
||||
.setUserAgent("Cryptomator VersionChecker/" + applicationVersion.orElse("SNAPSHOT"));
|
||||
.setUserAgent(userAgent);
|
||||
LOG.debug("Checking for updates...");
|
||||
try (CloseableHttpClient client = httpClientBuilder.build()) {
|
||||
HttpGet request = new HttpGet("https://api.cryptomator.org/updates/latestVersion.json");
|
||||
|
||||
@@ -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,9 +20,12 @@ import javafx.scene.control.OverrunStyle;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.Paint;
|
||||
|
||||
public class DirectoryListCell extends DraggableListCell<Vault> {
|
||||
|
||||
private static final Color UNLOCKED_ICON_COLOR = new Color(0.901, 0.494, 0.133, 1.0);
|
||||
private final Label statusText = new Label();
|
||||
private final Label nameText = new Label();
|
||||
private final Label pathText = new Label();
|
||||
@@ -45,7 +48,7 @@ public class DirectoryListCell extends DraggableListCell<Vault> {
|
||||
|
||||
MonadicBinding<Boolean> optionalItemIsUnlocked = EasyBind.monadic(itemProperty()).flatMap(Vault::unlockedProperty);
|
||||
statusText.textProperty().bind(optionalItemIsUnlocked.map(this::getStatusIconText));
|
||||
statusText.textFillProperty().bind(this.textFillProperty());
|
||||
statusText.textFillProperty().bind(EasyBind.combine(optionalItemIsUnlocked, textFillProperty(), this::getStatusIconColor));
|
||||
statusText.setMinSize(16.0, 16.0);
|
||||
statusText.setAlignment(Pos.CENTER);
|
||||
statusText.getStyleClass().add("fontawesome");
|
||||
@@ -67,6 +70,14 @@ public class DirectoryListCell extends DraggableListCell<Vault> {
|
||||
}
|
||||
}
|
||||
|
||||
private Paint getStatusIconColor(Boolean unlockedOrNull, Paint lockedValue) {
|
||||
if (Boolean.TRUE.equals(unlockedOrNull)) {
|
||||
return UNLOCKED_ICON_COLOR;
|
||||
} else {
|
||||
return lockedValue;
|
||||
}
|
||||
}
|
||||
|
||||
public void setVaultContextMenu(ContextMenu contextMenu) {
|
||||
this.vaultContextMenu = contextMenu;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
+1
-1
@@ -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;
|
||||
@@ -0,0 +1,106 @@
|
||||
/*******************************************************************************
|
||||
* 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;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.cryptomator.cryptolib.api.CryptoException;
|
||||
import org.cryptomator.frontend.webdav.mount.Mounter.CommandFailedException;
|
||||
import org.cryptomator.keychain.KeychainAccess;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Singleton
|
||||
public class AutoUnlocker {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AutoUnlocker.class);
|
||||
private static final int NAP_TIME_MILLIS = 500;
|
||||
|
||||
private final Optional<KeychainAccess> keychainAccess;
|
||||
private final VaultList vaults;
|
||||
private final ExecutorService executor;
|
||||
|
||||
@Inject
|
||||
public AutoUnlocker(Optional<KeychainAccess> keychainAccess, VaultList vaults, ExecutorService executor) {
|
||||
this.keychainAccess = keychainAccess;
|
||||
this.vaults = vaults;
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
public void unlockAllSilently() {
|
||||
Collection<Vault> vaultsToUnlock = vaults.stream().filter(this::shouldUnlockAfterStartup).collect(Collectors.toList());
|
||||
if (keychainAccess.isPresent() && !vaultsToUnlock.isEmpty()) {
|
||||
executor.submit(() -> unlockAll(vaultsToUnlock));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldUnlockAfterStartup(Vault vault) {
|
||||
return vault.getVaultSettings().unlockAfterStartup().get();
|
||||
}
|
||||
|
||||
private void unlockAll(Collection<Vault> vaults) {
|
||||
try {
|
||||
Iterator<Vault> iterator = vaults.iterator();
|
||||
assert iterator.hasNext() : "vaults must not be empty";
|
||||
unlockSilently(iterator.next());
|
||||
while (iterator.hasNext()) {
|
||||
Thread.sleep(NAP_TIME_MILLIS);
|
||||
unlockSilently(iterator.next());
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
LOG.warn("Auto unlock thread interrupted.");
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
private void unlockSilently(Vault vault) {
|
||||
char[] storedPw = keychainAccess.get().loadPassphrase(vault.getId());
|
||||
if (storedPw == null) {
|
||||
LOG.warn("No passphrase stored in keychain for vault registered for auto unlocking: {}", vault.getPath());
|
||||
}
|
||||
try {
|
||||
vault.unlock(CharBuffer.wrap(storedPw));
|
||||
mountSilently(vault);
|
||||
} catch (CryptoException e) {
|
||||
LOG.error("Auto unlock failed.", e);
|
||||
} finally {
|
||||
Arrays.fill(storedPw, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
private void mountSilently(Vault unlockedVault) {
|
||||
if (!unlockedVault.getVaultSettings().mountAfterUnlock().get()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
unlockedVault.mount();
|
||||
revealSilently(unlockedVault);
|
||||
} catch (CommandFailedException e) {
|
||||
LOG.error("Auto unlock succeded, but mounting the drive failed.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void revealSilently(Vault mountedVault) {
|
||||
if (!mountedVault.getVaultSettings().revealAfterMount().get()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mountedVault.reveal();
|
||||
} catch (CommandFailedException e) {
|
||||
LOG.error("Auto unlock succeded, but revealing the drive failed.", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
+1
-1
@@ -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.
|
||||
*
|
||||
@@ -16,16 +16,16 @@ import java.nio.file.FileSystem;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.LazyInitializer;
|
||||
import org.cryptomator.common.Optionals;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
import org.cryptomator.cryptofs.CryptoFileSystem;
|
||||
@@ -34,17 +34,18 @@ import org.cryptomator.cryptofs.CryptoFileSystemProvider;
|
||||
import org.cryptomator.cryptolib.api.CryptoException;
|
||||
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
|
||||
import org.cryptomator.frontend.webdav.WebDavServer;
|
||||
import org.cryptomator.frontend.webdav.mount.MountParams;
|
||||
import org.cryptomator.frontend.webdav.mount.Mounter.CommandFailedException;
|
||||
import org.cryptomator.frontend.webdav.mount.Mounter.Mount;
|
||||
import org.cryptomator.frontend.webdav.mount.Mounter.MountParam;
|
||||
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;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.binding.Binding;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
@@ -58,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<>();
|
||||
@@ -67,18 +67,17 @@ 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;
|
||||
}
|
||||
|
||||
// ******************************************************************************
|
||||
// Commands
|
||||
// ********************************************************************************/
|
||||
|
||||
private CryptoFileSystem getCryptoFileSystem(CharSequence passphrase) throws IOException {
|
||||
private CryptoFileSystem getCryptoFileSystem(CharSequence passphrase) throws IOException, CryptoException {
|
||||
return LazyInitializer.initializeLazily(cryptoFileSystem, () -> createCryptoFileSystem(passphrase), IOException.class);
|
||||
}
|
||||
|
||||
@@ -87,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 {
|
||||
@@ -101,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());
|
||||
}
|
||||
@@ -127,34 +124,43 @@ public class Vault {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void mount() {
|
||||
public synchronized void mount() throws CommandFailedException {
|
||||
if (servlet == null) {
|
||||
throw new IllegalStateException("Mounting requires unlocked WebDAV servlet.");
|
||||
}
|
||||
|
||||
Map<MountParam, String> mountOptions = new HashMap<>();
|
||||
mountOptions.put(MountParam.WIN_DRIVE_LETTER, vaultSettings.winDriveLetter().get());
|
||||
mountOptions.put(MountParam.PREFERRED_GVFS_SCHEME, settings.preferredGvfsScheme().get());
|
||||
MountParams mountParams = MountParams.create() //
|
||||
.withWindowsDriveLetter(vaultSettings.winDriveLetter().get()) //
|
||||
.withPreferredGvfsScheme(settings.preferredGvfsScheme().get()) //
|
||||
.build();
|
||||
|
||||
try {
|
||||
mount = servlet.mount(mountOptions);
|
||||
Platform.runLater(() -> {
|
||||
mounted.set(true);
|
||||
});
|
||||
} catch (CommandFailedException e) {
|
||||
LOG.error("Unable to mount filesystem", e);
|
||||
}
|
||||
mount = servlet.mount(mountParams);
|
||||
Platform.runLater(() -> {
|
||||
mounted.set(true);
|
||||
});
|
||||
}
|
||||
|
||||
public synchronized void unmount() throws Exception {
|
||||
public synchronized void unmount() throws CommandFailedException {
|
||||
unmount(Function.identity());
|
||||
}
|
||||
|
||||
public synchronized void unmountForced() throws CommandFailedException {
|
||||
unmount(Optionals.unwrap(Mount::forced));
|
||||
}
|
||||
|
||||
private synchronized void unmount(Function<Mount, ? extends UnmountOperation> unmountOperationChooser) throws CommandFailedException {
|
||||
if (mount != null) {
|
||||
mount.unmount();
|
||||
unmountOperationChooser.apply(mount).unmount();
|
||||
}
|
||||
Platform.runLater(() -> {
|
||||
mounted.set(false);
|
||||
});
|
||||
}
|
||||
|
||||
public boolean supportsForcedUnmount() {
|
||||
return mount != null && mount.forced().isPresent();
|
||||
}
|
||||
|
||||
public synchronized void lock() throws Exception {
|
||||
if (servlet != null) {
|
||||
servlet.stop();
|
||||
@@ -168,6 +174,30 @@ public class Vault {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ejects any mounted drives and locks this vault. no-op if this vault is currently locked.
|
||||
*/
|
||||
public void prepareForShutdown() {
|
||||
try {
|
||||
unmount();
|
||||
} catch (CommandFailedException e) {
|
||||
if (supportsForcedUnmount()) {
|
||||
try {
|
||||
unmountForced();
|
||||
} catch (CommandFailedException e1) {
|
||||
LOG.warn("Failed to force unmount vault.");
|
||||
}
|
||||
} else {
|
||||
LOG.warn("Failed to gracefully unmount vault.");
|
||||
}
|
||||
}
|
||||
try {
|
||||
lock();
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Failed to lock vault.");
|
||||
}
|
||||
}
|
||||
|
||||
public void reveal() throws CommandFailedException {
|
||||
if (mount != null) {
|
||||
mount.reveal();
|
||||
@@ -178,6 +208,10 @@ public class Vault {
|
||||
// Getter/Setter
|
||||
// *******************************************************************************/
|
||||
|
||||
public Observable[] observables() {
|
||||
return new Observable[] {unlocked, mounted};
|
||||
}
|
||||
|
||||
public VaultSettings getVaultSettings() {
|
||||
return vaultSettings;
|
||||
}
|
||||
|
||||
@@ -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,12 +15,11 @@ import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
import org.cryptomator.ui.model.VaultComponent.Builder;
|
||||
|
||||
@Singleton
|
||||
public class VaultFactory {
|
||||
|
||||
private final Builder vaultComponentBuilder;
|
||||
private final VaultComponent.Builder vaultComponentBuilder;
|
||||
private final ConcurrentMap<VaultSettings, Vault> vaults = new ConcurrentHashMap<>();
|
||||
|
||||
@Inject
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@@ -14,7 +14,9 @@ import javax.inject.Singleton;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
|
||||
import javafx.collections.ListChangeListener.Change;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.transformation.TransformationList;
|
||||
|
||||
@@ -59,15 +61,15 @@ public class VaultList extends TransformationList<Vault, VaultSettings> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sourceChanged(Change<? extends VaultSettings> c) {
|
||||
protected void sourceChanged(ListChangeListener.Change<? extends VaultSettings> c) {
|
||||
this.fireChange(new VaultListChange(c));
|
||||
}
|
||||
|
||||
private class VaultListChange extends Change<Vault> {
|
||||
private class VaultListChange extends ListChangeListener.Change<Vault> {
|
||||
|
||||
private final Change<? extends VaultSettings> delegate;
|
||||
private final ListChangeListener.Change<? extends VaultSettings> delegate;
|
||||
|
||||
public VaultListChange(Change<? extends VaultSettings> delegate) {
|
||||
public VaultListChange(ListChangeListener.Change<? extends VaultSettings> delegate) {
|
||||
super(VaultList.this);
|
||||
this.delegate = delegate;
|
||||
}
|
||||
@@ -77,6 +79,11 @@ public class VaultList extends TransformationList<Vault, VaultSettings> {
|
||||
return delegate.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasUpdated() {
|
||||
return delegate.wasUpdated();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
delegate.reset();
|
||||
@@ -94,27 +101,28 @@ public class VaultList extends TransformationList<Vault, VaultSettings> {
|
||||
|
||||
@Override
|
||||
public List<Vault> getRemoved() {
|
||||
List<Vault> removed = new ArrayList<>();
|
||||
for (VaultSettings s : delegate.getRemoved()) {
|
||||
removed.add(vaultFactory.get(s));
|
||||
}
|
||||
return removed;
|
||||
return Lists.transform(delegate.getRemoved(), vaultFactory::get);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasPermutated() {
|
||||
return delegate.wasPermutated();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int[] getPermutation() {
|
||||
if (delegate.wasPermutated()) {
|
||||
int len = getTo() - getFrom();
|
||||
int[] permutations = new int[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
permutations[i] = getPermutation(i);
|
||||
}
|
||||
return permutations;
|
||||
return IntStream.range(getFrom(), getTo()).map(delegate::getPermutation).toArray();
|
||||
} else {
|
||||
return new int[0];
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return delegate.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
@@ -34,11 +34,15 @@ public class DialogBuilderUtil {
|
||||
return buildDialog(title, header, content, Alert.AlertType.CONFIRMATION, defaultButton);
|
||||
}
|
||||
|
||||
private static Alert buildDialog(String title, String header, String content, Alert.AlertType type, ButtonType defaultButton) {
|
||||
public static Alert buildYesNoDialog(String title, String header, String content, ButtonType defaultButton) {
|
||||
return buildDialog(title, header, content, Alert.AlertType.CONFIRMATION, defaultButton, ButtonType.YES, ButtonType.NO);
|
||||
}
|
||||
|
||||
private static Alert buildDialog(String title, String header, String content, Alert.AlertType type, ButtonType defaultButton, ButtonType... buttons) {
|
||||
Text contentText = new Text(content);
|
||||
contentText.setWrappingWidth(360.0);
|
||||
|
||||
Alert alert = new Alert(type);
|
||||
Alert alert = new Alert(type, content, buttons);
|
||||
alert.setTitle(title);
|
||||
alert.setHeaderText(header);
|
||||
alert.getDialogPane().setContent(contentText);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<ChoiceBox GridPane.rowIndex="3" GridPane.columnIndex="1" fx:id="prefGvfsScheme" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
|
||||
|
||||
<!-- Row 4 -->
|
||||
<Label GridPane.rowIndex="4" GridPane.columnIndex="0" fx:id="debugModeLabel" text="%settings.debugMode.label" cacheShape="true" cache="true" />
|
||||
<Label GridPane.rowIndex="4" GridPane.columnIndex="0" text="%settings.debugMode.label" cacheShape="true" cache="true" />
|
||||
<CheckBox GridPane.rowIndex="4" GridPane.columnIndex="1" fx:id="debugModeCheckbox" cacheShape="true" cache="true" />
|
||||
|
||||
</children>
|
||||
|
||||
@@ -68,24 +68,24 @@
|
||||
</HBox>
|
||||
|
||||
<!-- Row 3.1 -->
|
||||
<Label GridPane.rowIndex="1" GridPane.columnIndex="0" text="%unlock.label.savePassword" cacheShape="true" cache="true" />
|
||||
<CheckBox GridPane.rowIndex="1" GridPane.columnIndex="1" fx:id="savePassword" onAction="#didClickSavePasswordCheckbox" cacheShape="true" cache="true" />
|
||||
<CheckBox GridPane.rowIndex="1" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="savePassword" text="%unlock.label.savePassword" onAction="#didClickSavePasswordCheckbox" cacheShape="true" cache="true" />
|
||||
|
||||
<!-- Row 3.2 -->
|
||||
<Label GridPane.rowIndex="2" GridPane.columnIndex="0" text="%unlock.label.mountAfterUnlock" cacheShape="true" cache="true" />
|
||||
<CheckBox GridPane.rowIndex="2" GridPane.columnIndex="1" fx:id="mountAfterUnlock" cacheShape="true" cache="true" />
|
||||
<CheckBox GridPane.rowIndex="2" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="unlockAfterStartup" text="%unlock.label.unlockAfterStartup" cacheShape="true" cache="true" />
|
||||
|
||||
<!-- Row 3.3 -->
|
||||
<Label GridPane.rowIndex="3" GridPane.columnIndex="0" text="%unlock.label.mountName" cacheShape="true" cache="true" />
|
||||
<TextField GridPane.rowIndex="3" GridPane.columnIndex="1" fx:id="mountName" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
|
||||
<CheckBox GridPane.rowIndex="3" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="mountAfterUnlock" text="%unlock.label.mountAfterUnlock" cacheShape="true" cache="true" />
|
||||
|
||||
<!-- Row 3.4 -->
|
||||
<Label GridPane.rowIndex="4" GridPane.columnIndex="0" text="%unlock.label.revealAfterMount" cacheShape="true" cache="true" />
|
||||
<CheckBox GridPane.rowIndex="4" GridPane.columnIndex="1" fx:id="revealAfterMount" cacheShape="true" cache="true" />
|
||||
<Label GridPane.rowIndex="4" GridPane.columnIndex="0" text="%unlock.label.mountName" cacheShape="true" cache="true" />
|
||||
<TextField GridPane.rowIndex="4" GridPane.columnIndex="1" fx:id="mountName" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
|
||||
|
||||
<!-- Row 3.5 -->
|
||||
<Label GridPane.rowIndex="5" GridPane.columnIndex="0" fx:id="winDriveLetterLabel" text="%unlock.label.winDriveLetter" cacheShape="true" cache="true" />
|
||||
<ChoiceBox GridPane.rowIndex="5" GridPane.columnIndex="1" fx:id="winDriveLetter" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
|
||||
<CheckBox GridPane.rowIndex="5" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="revealAfterMount" text="%unlock.label.revealAfterMount" cacheShape="true" cache="true" />
|
||||
|
||||
<!-- Row 3.6 -->
|
||||
<Label GridPane.rowIndex="6" GridPane.columnIndex="0" fx:id="winDriveLetterLabel" text="%unlock.label.winDriveLetter" cacheShape="true" cache="true" />
|
||||
<ChoiceBox GridPane.rowIndex="6" GridPane.columnIndex="1" fx:id="winDriveLetter" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
|
||||
</GridPane>
|
||||
|
||||
<!-- Row 4 -->
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
app.name = كريبتوماتور
|
||||
# main.fxml
|
||||
main.emptyListInstructions = اضغط هنا لاضافة محفظة
|
||||
main.directoryList.contextMenu.remove = ازل من القائمة
|
||||
main.directoryList.contextMenu.changePassword = تغيير كلمة المرور
|
||||
main.addDirectory.contextMenu.new = انشاء محفظة جديدة
|
||||
main.addDirectory.contextMenu.open = افتح محفظة موجوده
|
||||
# welcome.fxml
|
||||
welcome.checkForUpdates.label.currentlyChecking = فحص التحديثات
|
||||
welcome.newVersionMessage = يمكنك الان تحميل الاصدار رقم %1$s\nالاصدار الحالي %2$s
|
||||
# initialize.fxml
|
||||
initialize.label.password = كلمة المرور
|
||||
initialize.label.retypePassword = اعد كتابة كلمة المرور
|
||||
initialize.button.ok = انشاء محفظة
|
||||
initialize.messageLabel.alreadyInitialized = لقد تم تهيئة المحفظة
|
||||
initialize.messageLabel.initializationFailed = تعذر تهيئة المحفظة . يرجي مراجعة ملف التفاصيل ( log file )
|
||||
# notfound.fxml
|
||||
notfound.label = تعذر العثور علي المحفظه , هل قمت بنقلها ؟
|
||||
# upgrade.fxml
|
||||
upgrade.button = ترقية المحفظة
|
||||
upgrade.version3dropBundleExtension.msg = This vault needs to be migrated to a newer format.\n"%1$s" will be renamed to "%2$s".\nPlease make sure synchronization has finished before proceeding.
|
||||
upgrade.version3dropBundleExtension.err.alreadyExists = Automatic migration failed.\n"%s" already exists.
|
||||
# unlock.fxml
|
||||
unlock.label.password = كلمة المرور
|
||||
unlock.label.mountName = Drive Name
|
||||
unlock.label.winDriveLetter = Drive Letter
|
||||
unlock.label.downloadsPageLink = جميع اصدارات كريبتوماتور
|
||||
unlock.label.advancedHeading = خيارات اضافية
|
||||
unlock.button.unlock = افتح المحفظة
|
||||
unlock.button.advancedOptions.show = خيارات اكثر
|
||||
unlock.button.advancedOptions.hide = خيارات اقل
|
||||
unlock.choicebox.winDriveLetter.auto = دخول تلقائي
|
||||
unlock.errorMessage.wrongPassword = كلمة مرور خاطئة
|
||||
unlock.errorMessage.mountingFailed = فشل الدخول الي المحفظة . يرجي مراجعة ملف التفاصيل ( log file )
|
||||
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = محفظة غير مدعومة . هذه المحفظة تم انشاؤها بواسطة اصدار اقدم من كريبتوماتور
|
||||
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = محفظة غير مدعومة . هذه المحفظة تم انشاؤها بواسطة اصدار احدث من كريبتوماتور
|
||||
unlock.messageLabel.startServerFailed = Starting WebDAV server failed.
|
||||
# change_password.fxml
|
||||
changePassword.label.oldPassword = كلمة المرور القديمة
|
||||
changePassword.label.newPassword = كلمة المرور الجديدة
|
||||
changePassword.label.retypePassword = اعد كتابة كلمة المرور
|
||||
changePassword.label.downloadsPageLink = جميع اصدارات كريبتوماتور
|
||||
changePassword.button.change = تغيير كلمة المرور
|
||||
changePassword.errorMessage.wrongPassword = كلمة مرور خاطئة
|
||||
changePassword.errorMessage.decryptionFailed = فشل فك التشفير
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = اغلاق المحفظة
|
||||
unlocked.moreOptions.reveal = Reveal Drive
|
||||
unlocked.moreOptions.copyUrl = نسخ رابط ويب داف ( WebDAV )
|
||||
unlocked.label.revealFailed = Command failed
|
||||
unlocked.label.unmountFailed = Ejecting drive failed
|
||||
unlocked.label.statsEncrypted = مشفر
|
||||
unlocked.label.statsDecrypted = غير مشفر
|
||||
unlocked.ioGraph.yAxis.label = Throughput (MiB/s)
|
||||
# settings.fxml
|
||||
settings.version.label = الاصدار %s
|
||||
settings.checkForUpdates.label = افحص التحديثات
|
||||
settings.port.label = منفذ ويب داف ( WebDAV )
|
||||
settings.port.prompt = 0 \= Choose automatically
|
||||
settings.useipv6.label = Use IPv6 Literal
|
||||
settings.requiresRestartLabel = * Cryptomator needs to restart
|
||||
# tray icon
|
||||
tray.menu.open = فتح
|
||||
tray.menu.quit = اغلاق
|
||||
tray.infoMsg.title = لا يزال مستخدم
|
||||
tray.infoMsg.msg = Cryptomator is still alive. Quit it from the tray icon.
|
||||
tray.infoMsg.msg.osx = Cryptomator is still alive. Quit it from the menu bar icon.
|
||||
initialize.messageLabel.passwordStrength.0 = ضعيف جدا
|
||||
initialize.messageLabel.passwordStrength.1 = ضعيف
|
||||
initialize.messageLabel.passwordStrength.2 = عادي
|
||||
initialize.messageLabel.passwordStrength.3 = قوي
|
||||
initialize.messageLabel.passwordStrength.4 = قوي جدا
|
||||
initialize.label.doNotForget = هام \: في حالة نسيانك لكلمة المرور , لا يوجد طريقة لاستعادتها مره اخري
|
||||
main.directoryList.remove.confirmation.title = ازالة المحفظة
|
||||
main.directoryList.remove.confirmation.header = هل تريد فعلا ازالة المحفظة ؟
|
||||
main.directoryList.remove.confirmation.content = The vault will only be removed from the list. To permanently delete it, please delete the files from your filesystem.
|
||||
upgrade.version3to4.msg = This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding.
|
||||
upgrade.version3to4.err.io = Migration failed due to an I/O Exception. See log file for details.
|
||||
settings.prefGvfsScheme.label = WebDAV Scheme
|
||||
# upgrade.fxml
|
||||
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
|
||||
initialize.messageLabel.notEmpty = المحفظة غير فارغة
|
||||
unlock.label.savePassword = حفظ كلمة المرور
|
||||
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
|
||||
unlocked.label.mountFailed = Connecting drive failed
|
||||
unlock.savePassword.delete.confirmation.title = حذف كلمة المرور المحفوظة
|
||||
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
|
||||
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
|
||||
settings.debugMode.label = Debug Mode *
|
||||
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
|
||||
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
|
||||
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
|
||||
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
|
||||
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.
|
||||
settings.port.apply = Apply
|
||||
unlock.label.mountAfterUnlock = Mount Drive
|
||||
unlock.label.revealAfterMount = Reveal Drive
|
||||
@@ -0,0 +1,97 @@
|
||||
app.name = Криптоматор
|
||||
# main.fxml
|
||||
main.emptyListInstructions = Натиснете тук за да добавите сейф
|
||||
main.directoryList.contextMenu.remove = Премахнете от листа
|
||||
main.directoryList.contextMenu.changePassword = Сменете парола
|
||||
main.addDirectory.contextMenu.new = Създайте нов сейф
|
||||
main.addDirectory.contextMenu.open = Отворете съществуващ сейф
|
||||
# welcome.fxml
|
||||
welcome.checkForUpdates.label.currentlyChecking = Проверете за нови версии
|
||||
welcome.newVersionMessage = Version %1$s can be downloaded.\nThis is %2$s.
|
||||
# initialize.fxml
|
||||
initialize.label.password = Парола
|
||||
initialize.label.retypePassword = Повторете Паролата
|
||||
initialize.button.ok = Създайте Сейф
|
||||
initialize.messageLabel.alreadyInitialized = Сейфа е вече активен
|
||||
initialize.messageLabel.initializationFailed = Неуспешно активиране на сейф. Проверете лог файловете за повече информация.
|
||||
# notfound.fxml
|
||||
notfound.label = Сейфа не може да бъде намерен. Може би е бил преместен?
|
||||
# upgrade.fxml
|
||||
upgrade.button = Обновете версията на Сейф
|
||||
upgrade.version3dropBundleExtension.msg = This vault needs to be migrated to a newer format.\n"%1$s" will be renamed to "%2$s".\nPlease make sure synchronization has finished before proceeding.
|
||||
upgrade.version3dropBundleExtension.err.alreadyExists = Автоматичната миграция е неуспешна. "%s" вече съществува.
|
||||
# unlock.fxml
|
||||
unlock.label.password = Парола
|
||||
unlock.label.mountName = Име на диск
|
||||
unlock.label.winDriveLetter = Инициали на диск
|
||||
unlock.label.downloadsPageLink = Покажи всички версии на Криптоматор
|
||||
unlock.label.advancedHeading = Опции за напреднали
|
||||
unlock.button.unlock = Отключи Сейф
|
||||
unlock.button.advancedOptions.show = Покажи повече опции
|
||||
unlock.button.advancedOptions.hide = Покажи по-малко опции
|
||||
unlock.choicebox.winDriveLetter.auto = Автоматично наименование на Диска
|
||||
unlock.errorMessage.wrongPassword = Неправилна парола
|
||||
unlock.errorMessage.mountingFailed = Неуспешно активиране на диска. За повече информация вижте лог файла.
|
||||
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Неподържана версия. Този сейф е бил създаден със стара версия на Криптоматор.
|
||||
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Неподържана версия. Този сейф е бил създаден с по-нова версия на Криптоматор.
|
||||
unlock.messageLabel.startServerFailed = Неуспешно стартиране на WebDAV сървъра.
|
||||
# change_password.fxml
|
||||
changePassword.label.oldPassword = Стара парола
|
||||
changePassword.label.newPassword = Нова парола
|
||||
changePassword.label.retypePassword = Повторете паролата
|
||||
changePassword.label.downloadsPageLink = All Cryptomator versions
|
||||
changePassword.button.change = Смени паролата
|
||||
changePassword.errorMessage.wrongPassword = Неправилна парола
|
||||
changePassword.errorMessage.decryptionFailed = Неуспешно декриптиране
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = Заключи Сейфа
|
||||
unlocked.moreOptions.reveal = Покажи
|
||||
unlocked.moreOptions.copyUrl = Copy WebDAV URL
|
||||
unlocked.label.revealFailed = Командата е неуспешна
|
||||
unlocked.label.unmountFailed = Ejecting drive failed
|
||||
unlocked.label.statsEncrypted = encrypted
|
||||
unlocked.label.statsDecrypted = decrypted
|
||||
unlocked.ioGraph.yAxis.label = Throughput (MiB/s)
|
||||
# settings.fxml
|
||||
settings.version.label = Version %s
|
||||
settings.checkForUpdates.label = Check for Updates
|
||||
settings.port.label = WebDAV Port
|
||||
settings.port.prompt = 0 \= Choose automatically
|
||||
settings.useipv6.label = Use IPv6 Literal
|
||||
settings.requiresRestartLabel = * Cryptomator needs to restart
|
||||
# tray icon
|
||||
tray.menu.open = Open
|
||||
tray.menu.quit = Quit
|
||||
tray.infoMsg.title = Still Running
|
||||
tray.infoMsg.msg = Cryptomator is still alive. Quit it from the tray icon.
|
||||
tray.infoMsg.msg.osx = Cryptomator is still alive. Quit it from the menu bar icon.
|
||||
initialize.messageLabel.passwordStrength.0 = Very weak
|
||||
initialize.messageLabel.passwordStrength.1 = Weak
|
||||
initialize.messageLabel.passwordStrength.2 = Fair
|
||||
initialize.messageLabel.passwordStrength.3 = Strong
|
||||
initialize.messageLabel.passwordStrength.4 = Very strong
|
||||
initialize.label.doNotForget = IMPORTANT\: If you forget your password, there is no way to recover your data.
|
||||
main.directoryList.remove.confirmation.title = Remove Vault
|
||||
main.directoryList.remove.confirmation.header = Do you really want to remove this vault?
|
||||
main.directoryList.remove.confirmation.content = The vault will only be removed from the list. To permanently delete it, please delete the files from your filesystem.
|
||||
upgrade.version3to4.msg = This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding.
|
||||
upgrade.version3to4.err.io = Migration failed due to an I/O Exception. See log file for details.
|
||||
settings.prefGvfsScheme.label = WebDAV Scheme
|
||||
# upgrade.fxml
|
||||
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
|
||||
initialize.messageLabel.notEmpty = Vault not empty
|
||||
unlock.label.savePassword = Save Password
|
||||
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
|
||||
unlocked.label.mountFailed = Connecting drive failed
|
||||
unlock.savePassword.delete.confirmation.title = Delete Saved Password
|
||||
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
|
||||
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
|
||||
settings.debugMode.label = Debug Mode *
|
||||
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
|
||||
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
|
||||
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
|
||||
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
|
||||
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.
|
||||
settings.port.apply = Apply
|
||||
unlock.label.mountAfterUnlock = Mount Drive
|
||||
unlock.label.revealAfterMount = Reveal Drive
|
||||
@@ -0,0 +1,97 @@
|
||||
app.name = Cryptomator
|
||||
# main.fxml
|
||||
main.emptyListInstructions = Tryk her for at tilføje en ny Vault
|
||||
main.directoryList.contextMenu.remove = Fjern fra listen
|
||||
main.directoryList.contextMenu.changePassword = Skift adgangskode
|
||||
main.addDirectory.contextMenu.new = Opret ny Vault
|
||||
main.addDirectory.contextMenu.open = Åben en eksisterende Vault
|
||||
# welcome.fxml
|
||||
welcome.checkForUpdates.label.currentlyChecking = Tjek for opdateringer
|
||||
welcome.newVersionMessage = Version %1$s kan nu hentes.\nDette er %2$s.
|
||||
# initialize.fxml
|
||||
initialize.label.password = Adgangskode
|
||||
initialize.label.retypePassword = Gentag Adgangskode
|
||||
initialize.button.ok = Opret Vault
|
||||
initialize.messageLabel.alreadyInitialized = Vault er allerede initialiseret
|
||||
initialize.messageLabel.initializationFailed = Kunne ikke initialisere Vault. Se logfilen for yderligere detaljer.
|
||||
# notfound.fxml
|
||||
notfound.label = Vault'en kunne ikke findes. Er den blevet flyttet?
|
||||
# upgrade.fxml
|
||||
upgrade.button = Opgradér Vault
|
||||
upgrade.version3dropBundleExtension.msg = Denne Vault skal migreres til et nyere format.\n"%1$s" vil blive omdøbt til "%2$s".\nVent venligst til al synkronisering er gennemført, inden du fortsætter.
|
||||
upgrade.version3dropBundleExtension.err.alreadyExists = Automatisk migrering fejlede.\n"%s" eksisterer allerede.
|
||||
# unlock.fxml
|
||||
unlock.label.password = Adgangskode
|
||||
unlock.label.mountName = Drev navn
|
||||
unlock.label.winDriveLetter = Drev bogstav
|
||||
unlock.label.downloadsPageLink = Alle Cryptomator versioner
|
||||
unlock.label.advancedHeading = Avancerede Indstillinger
|
||||
unlock.button.unlock = Lås op for Vault
|
||||
unlock.button.advancedOptions.show = Flere valgmuligheder
|
||||
unlock.button.advancedOptions.hide = Færre valgmuligheder
|
||||
unlock.choicebox.winDriveLetter.auto = Tildel automatisk
|
||||
unlock.errorMessage.wrongPassword = Forkert adgangskode
|
||||
unlock.errorMessage.mountingFailed = Montering fejlede. Se logfilen for yderligere detaljer.
|
||||
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Ikke-understøttet Vault. Denne Vault er blevet oprettet med en ældre version af Cryptomator.
|
||||
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Ikke-understøttet Vault. Denne Vault er blevet oprettet med en nyere version af Cryptomator.
|
||||
unlock.messageLabel.startServerFailed = Kunne ikke starte WebDAV server.
|
||||
# change_password.fxml
|
||||
changePassword.label.oldPassword = Gammel adgangskode
|
||||
changePassword.label.newPassword = Ny adgangskode
|
||||
changePassword.label.retypePassword = Gentag adgangskode
|
||||
changePassword.label.downloadsPageLink = Alle Cryptomator versioner
|
||||
changePassword.button.change = Skift adgangskode
|
||||
changePassword.errorMessage.wrongPassword = Forkert adgangskode
|
||||
changePassword.errorMessage.decryptionFailed = Dekryptering fejlede
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = Lås Vault
|
||||
unlocked.moreOptions.reveal = Vis drev
|
||||
unlocked.moreOptions.copyUrl = Kopier WebDAV URL
|
||||
unlocked.label.revealFailed = Kommando fejlede
|
||||
unlocked.label.unmountFailed = Afmontering af drev fejlede
|
||||
unlocked.label.statsEncrypted = Krypteret
|
||||
unlocked.label.statsDecrypted = Dekrypteret
|
||||
unlocked.ioGraph.yAxis.label = Throughput (MiB/s)
|
||||
# settings.fxml
|
||||
settings.version.label = Version %s
|
||||
settings.checkForUpdates.label = Tjek for opdateringer
|
||||
settings.port.label = WebDAV Port
|
||||
settings.port.prompt = 0 \= Vælg automatisk
|
||||
settings.useipv6.label = Brug IPv6 adresse
|
||||
settings.requiresRestartLabel = * Cryptomator skal genstartes
|
||||
# tray icon
|
||||
tray.menu.open = Åbn
|
||||
tray.menu.quit = Afslut
|
||||
tray.infoMsg.title = Kører Stadig
|
||||
tray.infoMsg.msg = Cryptomator kører stadig. Afslut programmet fra tray-ikonet.
|
||||
tray.infoMsg.msg.osx = Cryptomator kører stadig. Afslut programmet fra menu-baren.
|
||||
initialize.messageLabel.passwordStrength.0 = Meget svag
|
||||
initialize.messageLabel.passwordStrength.1 = Svag
|
||||
initialize.messageLabel.passwordStrength.2 = Mellem
|
||||
initialize.messageLabel.passwordStrength.3 = Stærk
|
||||
initialize.messageLabel.passwordStrength.4 = Meget stærk
|
||||
initialize.label.doNotForget = VIGTIGT\: Hvis du glemmer dit password, er der ingen måde hvorpå data kan genskabes.
|
||||
main.directoryList.remove.confirmation.title = Slet Vault
|
||||
main.directoryList.remove.confirmation.header = Er du sikker på at du vil slette denne Vault?
|
||||
main.directoryList.remove.confirmation.content = Valgte Vault vil kun blive slettet fra listen. For at slette denne permanent, skal du slette filerne fra dit filsystem.
|
||||
upgrade.version3to4.msg = Denne Vault skal migreres til et nyere format.\nDe krypterede foldernavne vil blive opdateret.\nVent venligst til al synkronisering er gennemført, inden du fortsætter.
|
||||
upgrade.version3to4.err.io = Migrering fejlede pga. en I/O fejl. Se logfilen for yderligere detaljer.
|
||||
settings.prefGvfsScheme.label = WebDAV Scheme
|
||||
# upgrade.fxml
|
||||
upgrade.confirmation.label = Ja, jeg har sikret mig at al synkronisering er gennemført.
|
||||
initialize.messageLabel.notEmpty = Vault er ikke tom
|
||||
unlock.label.savePassword = Gem adgangskode
|
||||
unlock.errorMessage.unauthenticVersionMac = Kunne ikke autentificere versions-MAC
|
||||
unlocked.label.mountFailed = Montering af drev fejlede
|
||||
unlock.savePassword.delete.confirmation.title = Slet gemt adgangskode
|
||||
unlock.savePassword.delete.confirmation.header = Er du sikker på at du vil slette den til Vault'en gemte adgangskode?
|
||||
unlock.savePassword.delete.confirmation.content = Den til Vault'en gemte adgangskode vil blive slettet fra dit systems keychain med øjeblikkelig virkning. Hvis du vil gemme din adgangskode på ny, skal du låse din Vault op med indstillingen "Gem adgangskode" slået til.
|
||||
settings.debugMode.label = Debug Tilstand *
|
||||
upgrade.version3dropBundleExtension.title = Vault Version 3 Opgradering (Drop Bundle Extension)
|
||||
upgrade.version3to4.title = Vault Version 3 til 4 Opgradering
|
||||
upgrade.version4to5.title = Vault Version 4 til 5 Opgradering
|
||||
upgrade.version4to5.msg = Denne Vault skal migreres til et nyere format.\nDe krypterede filer vil blive opdateret.\nVent venligst til al synkronisering er gennemført, inden du fortsætter.\n\nNote\: Denne proces vil påvirke ændringsdato og -tidspunkt for samtlige filer.
|
||||
upgrade.version4to5.err.io = Migrering fejlede pga. en I/O fejl. Se logfilen for yderligere detaljer.
|
||||
settings.port.apply = Gem
|
||||
unlock.label.mountAfterUnlock = Monter drev
|
||||
unlock.label.revealAfterMount = Vis drev
|
||||
@@ -52,12 +52,6 @@ unlocked.label.unmountFailed = Trennen des Laufwerks fehlgeschlagen
|
||||
unlocked.label.statsEncrypted = verschlüsselt
|
||||
unlocked.label.statsDecrypted = entschlüsselt
|
||||
unlocked.ioGraph.yAxis.label = Durchsatz (MiB/s)
|
||||
# mac_warnings.fxml
|
||||
macWarnings.windowTitle = Achtung - Kompromittierte Datei in %s
|
||||
# "potentially detected" or "potentially malicious"?
|
||||
macWarnings.message = Cryptomator hat möglicherweise unerlaubte Veränderungen in den folgenden Dateien erkannt\:
|
||||
macWarnings.moreInformationButton = Mehr erfahren
|
||||
macWarnings.whitelistButton = Trotzdem entschlüsseln
|
||||
# settings.fxml
|
||||
settings.version.label = Version %s
|
||||
settings.checkForUpdates.label = Auf Updates prüfen
|
||||
@@ -97,4 +91,7 @@ upgrade.version3dropBundleExtension.title = Upgrade Tresor-Version 3 (Entfall de
|
||||
upgrade.version3to4.title = Upgrade Tresor-Version 3 zu 4
|
||||
upgrade.version4to5.title = Upgrade Tresor-Version 4 zu 5
|
||||
upgrade.version4to5.msg = Dieser Tresor muss auf ein neueres Format aktualisiert werden.\nVerschlüsselte Dateien werden dabei aktualisiert.\nStellen Sie bitte sicher, dass derzeit keine Synchronisation stattfindet.\n\nHinweis\: Beim Upgrade wird das Änderungsdatum aller Dateien auf das aktuelle Datum geändert.
|
||||
upgrade.version4to5.err.io = Migration aufgrund eines I/O-Fehlers fehlgeschlagen.\nWeitere Informationen in der Log-Datei.
|
||||
upgrade.version4to5.err.io = Migration aufgrund eines I/O-Fehlers fehlgeschlagen.\nWeitere Informationen in der Log-Datei.
|
||||
settings.port.apply = Anwenden
|
||||
unlock.label.mountAfterUnlock = Laufwerk verbinden
|
||||
unlock.label.revealAfterMount = Laufwerk anzeigen
|
||||
@@ -59,6 +59,7 @@ unlock.label.password=Password
|
||||
unlock.label.savePassword=Save Password
|
||||
unlock.label.mountAfterUnlock=Mount Drive
|
||||
unlock.label.mountName=Drive Name
|
||||
unlock.label.unlockAfterStartup=Auto-Unlock on Start (Experimental)
|
||||
unlock.label.revealAfterMount=Reveal Drive
|
||||
unlock.label.winDriveLetter=Drive Letter
|
||||
unlock.label.downloadsPageLink=All Cryptomator versions
|
||||
@@ -96,6 +97,9 @@ unlocked.label.unmountFailed=Ejecting drive failed
|
||||
unlocked.label.statsEncrypted=encrypted
|
||||
unlocked.label.statsDecrypted=decrypted
|
||||
unlocked.ioGraph.yAxis.label=Throughput (MiB/s)
|
||||
unlocked.lock.force.confirmation.title=Locking of %1$s failed
|
||||
unlocked.lock.force.confirmation.header=Do you want to force locking?
|
||||
unlocked.lock.force.confirmation.content=This may be because other programs are still accessing files in the vault or because some other problem occurred.\n\nPrograms still accessing the files may not work correctly and data not already written by those programs may be lost.
|
||||
|
||||
# settings.fxml
|
||||
settings.version.label=Version %s
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
app.name = Cryptomator
|
||||
# main.fxml
|
||||
main.emptyListInstructions = Clic aquí para añadir una caja fuerte
|
||||
main.emptyListInstructions = Haz clic aquí para añadir una caja fuerte
|
||||
# should it be imperative?
|
||||
main.directoryList.contextMenu.remove = Eliminar de la lista
|
||||
main.directoryList.contextMenu.changePassword = Cambiar la contraseña
|
||||
main.addDirectory.contextMenu.new = Crear una nueva caja fuerte
|
||||
main.addDirectory.contextMenu.open = Abrir una caja fuerte existente
|
||||
# welcome.fxml
|
||||
welcome.checkForUpdates.label.currentlyChecking = Chequando por actualizaciónes...
|
||||
welcome.newVersionMessage = Se puede bajar version %1$s.\nEste es %2$s.
|
||||
welcome.checkForUpdates.label.currentlyChecking = Comprobando actualizaciones...
|
||||
welcome.newVersionMessage = La versión %1$s está disponible para descargar.\nLa versión actual es %2$s.
|
||||
# initialize.fxml
|
||||
initialize.label.password = Contraseña
|
||||
initialize.label.retypePassword = Reintroduzca contraseña
|
||||
initialize.label.retypePassword = Repetir contraseña
|
||||
initialize.button.ok = Crear caja fuerte
|
||||
initialize.messageLabel.alreadyInitialized = Caja fuerte ya está inicializado
|
||||
initialize.messageLabel.alreadyInitialized = La caja fuerte ya está inicializada
|
||||
initialize.messageLabel.initializationFailed = No se pudo inicializar la caja fuerte. Ver archivo de registro para detalles.
|
||||
# notfound.fxml
|
||||
notfound.label = No se pudo encontrar la caja fuerte. Se movió a otro lugar?
|
||||
@@ -23,48 +23,43 @@ upgrade.version3dropBundleExtension.msg = Este caja fuerte se debe actualizar a
|
||||
upgrade.version3dropBundleExtension.err.alreadyExists = Migración automática ha fallado.\n"%s" ya existe.
|
||||
# unlock.fxml
|
||||
unlock.label.password = Contraseña
|
||||
unlock.label.mountName = Nombre del disco
|
||||
unlock.label.winDriveLetter = Letra del disco
|
||||
unlock.label.mountName = Nombre de la unidad
|
||||
unlock.label.winDriveLetter = Letra de la unidad
|
||||
unlock.label.downloadsPageLink = Todas las versiones de Cryptomator
|
||||
unlock.label.advancedHeading = Opciones avanzadas
|
||||
unlock.button.unlock = Abrir caja fuerte
|
||||
unlock.button.unlock = Desbloquear caja fuerte
|
||||
unlock.button.advancedOptions.show = Más opciones
|
||||
unlock.button.advancedOptions.hide = Menos opciones
|
||||
unlock.choicebox.winDriveLetter.auto = Asignar automáticamente
|
||||
unlock.errorMessage.wrongPassword = Contraseña incorrecta
|
||||
unlock.errorMessage.mountingFailed = Monteo ha fallado. Ver archivo del registro para detalles.
|
||||
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Caja fuerte insupportado. Este caja se ha creado con una versión pasada de Cryptomator.
|
||||
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Caja fuerte insupportado. Este caja se ha creado con una versión nueva de Cryptomator.
|
||||
unlock.errorMessage.mountingFailed = El montaje ha fallado. Ver archivo del registro para detalles.
|
||||
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Caja fuerte no soportada. Ésta caja se ha creado con una versión anterior de Cryptomator.
|
||||
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Caja fuerte no soportada. Ésta caja se ha creado con una versión nueva de Cryptomator.
|
||||
unlock.messageLabel.startServerFailed = Iniciación del servidor de WebDAV ha fallado.
|
||||
# change_password.fxml
|
||||
changePassword.label.oldPassword = Contraseña anterior
|
||||
changePassword.label.oldPassword = Contraseña antigua
|
||||
# Can also use "current password" = "contraseña actual"
|
||||
changePassword.label.newPassword = Nueva contraseña
|
||||
changePassword.label.retypePassword = Reintroduzca contraseña
|
||||
changePassword.label.retypePassword = Repetir contraseña
|
||||
changePassword.label.downloadsPageLink = Todas las versiones de Cryptomator
|
||||
changePassword.button.change = Cambiar contraseña
|
||||
changePassword.errorMessage.wrongPassword = Contraseña incorrecta
|
||||
changePassword.errorMessage.decryptionFailed = Decifración ha fallado
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = Encerrar caja fuerte
|
||||
unlocked.moreOptions.reveal = Mostrar disco
|
||||
unlocked.moreOptions.reveal = Revelar unidad
|
||||
unlocked.moreOptions.copyUrl = Copiar URL de WebDAV
|
||||
unlocked.label.revealFailed = Comando ha fallado
|
||||
unlocked.label.unmountFailed = Expulsar el disco ha fallado
|
||||
unlocked.label.statsEncrypted = cifrado
|
||||
unlocked.label.statsDecrypted = decifrado
|
||||
unlocked.ioGraph.yAxis.label = Procesamiento (MiB/s)
|
||||
# mac_warnings.fxml
|
||||
macWarnings.windowTitle = Peligro - archivo corrupto en %s
|
||||
macWarnings.message = Cryptomator ha detectado corrupciones malciosas en los seguientes archivos\:
|
||||
macWarnings.moreInformationButton = Aprende más
|
||||
macWarnings.whitelistButton = Decifrar selecionado de todos modos
|
||||
# settings.fxml
|
||||
settings.version.label = Version %s
|
||||
settings.checkForUpdates.label = Chequear por actualizaciones
|
||||
settings.port.label = Puerta de WebDAV *
|
||||
settings.port.prompt = 0 \= Elige automáticamente
|
||||
settings.useipv6.label = Usa literal de IPv6
|
||||
settings.version.label = Versión %s
|
||||
settings.checkForUpdates.label = Comprobar actualizaciones
|
||||
settings.port.label = Puerto WebDAV
|
||||
settings.port.prompt = 0 \= Elegir automáticamente
|
||||
settings.useipv6.label = Usar IPv6 literal
|
||||
settings.requiresRestartLabel = * Cryptomator se necesita reiniciar
|
||||
# tray icon
|
||||
tray.menu.open = Abrir
|
||||
@@ -72,31 +67,34 @@ tray.menu.quit = Salir
|
||||
tray.infoMsg.title = Todavía en ejecución
|
||||
tray.infoMsg.msg = Cryptomator todavía esta en ejecución. Para salir usa el icono del tray.
|
||||
tray.infoMsg.msg.osx = Cryptomator todavía esta en ejecución. Para salir usa el icono de la barra del menú.
|
||||
initialize.messageLabel.passwordStrength.0 = muy débil
|
||||
initialize.messageLabel.passwordStrength.1 = débil
|
||||
initialize.messageLabel.passwordStrength.2 = suficiente
|
||||
initialize.messageLabel.passwordStrength.3 = fuerte
|
||||
initialize.messageLabel.passwordStrength.4 = muy fuerte
|
||||
initialize.label.doNotForget = IMPORTANTE\: Si olivdes tú contraseña, no hay ninguna manera de recuperar tus datos.
|
||||
initialize.messageLabel.passwordStrength.0 = Muy débil
|
||||
initialize.messageLabel.passwordStrength.1 = Débil
|
||||
initialize.messageLabel.passwordStrength.2 = Suficiente
|
||||
initialize.messageLabel.passwordStrength.3 = Fuerte
|
||||
initialize.messageLabel.passwordStrength.4 = Muy fuerte
|
||||
initialize.label.doNotForget = IMPORTANTE\: Si olivdas tú contraseña, no hay ninguna manera de recuperar tus datos.
|
||||
main.directoryList.remove.confirmation.title = Borrar caja fuerte
|
||||
main.directoryList.remove.confirmation.header = ¿Quieres de verdad borrar este caja fuerte?
|
||||
main.directoryList.remove.confirmation.header = ¿Quieres de verdad borrar esta caja fuerte?
|
||||
main.directoryList.remove.confirmation.content = La caja fuerte solo se borra de la lista. Para eliminarla permanente por favor elimina los datos de tú sistema de archivos.
|
||||
upgrade.version3to4.msg = Este caja fuerte se debe migrar a un formato más reciente.\nLos nombres de las carpetas cifradas se actualizan.\nPor favor asegurarse de que la sincronización ha terminado antes de seguir.
|
||||
upgrade.version3to4.err.io = Migración ha fallado por causa de una excepción I/O. Para detalles revisa el archivo de registro.
|
||||
# or esequema WEBDAV but I think sistema sounds better
|
||||
settings.prefGvfsScheme.label = sistema WebDAV
|
||||
settings.prefGvfsScheme.label = Esquema WebDAV
|
||||
# upgrade.fxml
|
||||
upgrade.confirmation.label = Sí, me he asegurado de que la sincronización ha terminado
|
||||
initialize.messageLabel.notEmpty = Caja fuerte no está vacio
|
||||
unlock.label.savePassword = Contraseña segura
|
||||
unlock.errorMessage.unauthenticVersionMac = No se pudo autentificar la version de MAC.
|
||||
unlocked.label.mountFailed = Connecting drive failed
|
||||
unlock.savePassword.delete.confirmation.title = Delete Saved Password
|
||||
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
|
||||
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
|
||||
settings.debugMode.label = Debug Mode *
|
||||
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
|
||||
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
|
||||
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
|
||||
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
|
||||
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.
|
||||
initialize.messageLabel.notEmpty = Caja fuerte no está vacia
|
||||
unlock.label.savePassword = Guardar contraseña
|
||||
unlock.errorMessage.unauthenticVersionMac = No se pudo autentificar la versión de MAC.
|
||||
unlocked.label.mountFailed = Error al montar la unidad
|
||||
unlock.savePassword.delete.confirmation.title = Borrar contraseña guardada
|
||||
unlock.savePassword.delete.confirmation.header = ¿Quieres borrar la contraseña guardada de esta unidad?
|
||||
unlock.savePassword.delete.confirmation.content = La contraseña guardada de esta caja fuerte, será borrada inmediatamente del sistema de claves. Si quieres guardar tu contraseña de nuevo, tienes que volver a desbloquear la caja fuerte marcando la opción de "Guardar contraseña".
|
||||
settings.debugMode.label = Modo depuración *
|
||||
upgrade.version3dropBundleExtension.title = Actualizar caja fuerte a la versión 3 (Drop Bundle Extension)
|
||||
upgrade.version3to4.title = Actualizar caja fuerte de versión 3 a 4
|
||||
upgrade.version4to5.title = Actualizar caja fuerte de versión 3 a 4
|
||||
upgrade.version4to5.msg = Esta caja fuerte tiene que ser migrada a un formato nuevo.\nLos archivos encriptados se actualizarán.\nPor favor, asegúrate de que la sincronización ha terminado antes de empezar con el proceso.\n\nNota\: Las fechas de modificación de todos los archivos, se cambiarán a la fecha actual.
|
||||
upgrade.version4to5.err.io = La migración ha fallado por una excepción E/S. Consulta el log para ver más detalles.
|
||||
settings.port.apply = Aplicar
|
||||
unlock.label.mountAfterUnlock = Montar unidad
|
||||
unlock.label.revealAfterMount = Revelar unidad
|
||||
@@ -55,11 +55,6 @@ unlocked.label.statsEncrypted = chiffré
|
||||
# Décryptage signifie récupérer les données en clair tout en ne connaissant pas la clé
|
||||
unlocked.label.statsDecrypted = déchiffré
|
||||
unlocked.ioGraph.yAxis.label = Débit (MiB/s)
|
||||
# mac_warnings.fxml
|
||||
macWarnings.windowTitle = Attention - Fichier corrompu dans %s
|
||||
macWarnings.message = Cryptomator a détecté des corruptions de données dans les fichiers suivants \:
|
||||
macWarnings.moreInformationButton = En savoir plus
|
||||
macWarnings.whitelistButton = Déchiffrer tout de même
|
||||
# settings.fxml
|
||||
settings.version.label = Version %s
|
||||
settings.checkForUpdates.label = Vérif. des mises à jour
|
||||
@@ -99,4 +94,7 @@ upgrade.version3dropBundleExtension.title = mise à jour vers la version 3 du co
|
||||
upgrade.version3to4.title = metre à jour le coffre de la version 3 à la version 4
|
||||
upgrade.version4to5.title = metre à jour le coffre de la version 4 à la version 5
|
||||
upgrade.version4to5.msg = ce coffre doit être mis à jour vers un format plus récent.\nles fichiés chiffrés seront mis à jour.\nVeuillez vérifier que la synchronisation est terminée avant de commencer.\n\nNote \: la date de modification des fichiers sera mise à jour avec la date courante.
|
||||
upgrade.version4to5.err.io = Migration échouée due à une erreur de lecture. Lisez les logs pour plus de détails.
|
||||
upgrade.version4to5.err.io = Migration échouée due à une erreur de lecture. Lisez les logs pour plus de détails.
|
||||
settings.port.apply = Appliquer
|
||||
unlock.label.mountAfterUnlock = Monter un lecteur
|
||||
unlock.label.revealAfterMount = Voir le lecteur
|
||||
@@ -52,11 +52,6 @@ unlocked.label.unmountFailed = Meghajtó leválasztása sikertelen
|
||||
unlocked.label.statsEncrypted = titkosított
|
||||
unlocked.label.statsDecrypted = titkosítás feloldva
|
||||
unlocked.ioGraph.yAxis.label = Teljesítmény (MiB/s)
|
||||
# mac_warnings.fxml
|
||||
macWarnings.windowTitle = Veszély - Korrupt fájl a következőben\: %s
|
||||
macWarnings.message = Cryptomator potenciálisan rosszindulatú hibákat fedezett fel a következő fájlokban\:
|
||||
macWarnings.moreInformationButton = Tudj meg többet
|
||||
macWarnings.whitelistButton = Kiválasztottak titkosításának feloldása mindenképp
|
||||
# settings.fxml
|
||||
settings.version.label = Verzió\: %s
|
||||
settings.checkForUpdates.label = Frissítések keresése
|
||||
@@ -96,4 +91,7 @@ upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle
|
||||
upgrade.version3to4.title = Széf verziófrissítése 3-ról 4-re
|
||||
upgrade.version4to5.title = Széf verziófrissítése 4-ről 5-re
|
||||
upgrade.version4to5.msg = Ennek a széfnek egy újabb formátumra való migrációja szükséges. A titkosított könyvtárnevek frissítve lesznek. Kérlek, győződj meg a szinkronizáció befejeztéről mielőtt továbblépnél.\n\nMegjegyzés\: A összes fájl módosításának dátuma az aktuális időre fog módosulni
|
||||
upgrade.version4to5.err.io = Migráció meghíusúlt egy I/O kivétel miatt. Kérlek nézd meg a naplófájlt a további részletekért.
|
||||
upgrade.version4to5.err.io = Migráció meghíusúlt egy I/O kivétel miatt. Kérlek nézd meg a naplófájlt a további részletekért.
|
||||
settings.port.apply = Apply
|
||||
unlock.label.mountAfterUnlock = Mount Drive
|
||||
unlock.label.revealAfterMount = Reveal Drive
|
||||
@@ -52,11 +52,6 @@ unlocked.label.unmountFailed = Espulsione disco fallita
|
||||
unlocked.label.statsEncrypted = criptato
|
||||
unlocked.label.statsDecrypted = decriptato
|
||||
unlocked.ioGraph.yAxis.label = Volume dati (MiB/s)
|
||||
# mac_warnings.fxml
|
||||
macWarnings.windowTitle = Pericolo - File corroto in %s
|
||||
macWarnings.message = Cryptomator ha individuato potenziali pericolose corruzioni nei seguenti file\:
|
||||
macWarnings.moreInformationButton = Più informazioni
|
||||
macWarnings.whitelistButton = Decripta i selezionati comunque
|
||||
# settings.fxml
|
||||
settings.version.label = Versione %s
|
||||
settings.checkForUpdates.label = Verifica aggiornamenti
|
||||
@@ -79,21 +74,24 @@ initialize.label.doNotForget = IMPORTANTE\: Se dimentichi la password, non c'è
|
||||
main.directoryList.remove.confirmation.title = Rimuovi vault
|
||||
main.directoryList.remove.confirmation.header = Vuoi davvero rimuovere questo vault?
|
||||
main.directoryList.remove.confirmation.content = Il vault sarà rimosso solo dalla lista. Per eliminarlo definitivamente, elimina per favore i file dal tuo hard disk.
|
||||
upgrade.version3to4.msg = This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding.
|
||||
upgrade.version3to4.err.io = Migration failed due to an I/O Exception. See log file for details.
|
||||
settings.prefGvfsScheme.label = WebDAV Scheme
|
||||
upgrade.version3to4.msg = Il vault deve ha bisogno di essere migrato in un nuovo formato. I nome delle cartelle criptate saranno aggiornati. Per favore assicurati che la sincronizzazione sia terminata prima di procedere.
|
||||
upgrade.version3to4.err.io = Migrazione fallita a causa di una eccezione I/O. Verificare i file di log per i dettagli.
|
||||
settings.prefGvfsScheme.label = Schema WebDAV
|
||||
# upgrade.fxml
|
||||
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
|
||||
initialize.messageLabel.notEmpty = Vault not empty
|
||||
unlock.label.savePassword = Save Password
|
||||
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
|
||||
unlocked.label.mountFailed = Connecting drive failed
|
||||
unlock.savePassword.delete.confirmation.title = Delete Saved Password
|
||||
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
|
||||
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
|
||||
settings.debugMode.label = Debug Mode *
|
||||
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
|
||||
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
|
||||
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
|
||||
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
|
||||
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.
|
||||
upgrade.confirmation.label = Si, sono sicuro che la sincronizzazione e' terminata
|
||||
initialize.messageLabel.notEmpty = Vault non vuoto
|
||||
unlock.label.savePassword = Salva Password
|
||||
unlock.errorMessage.unauthenticVersionMac = Non riesco ad autenticare la versione MAC.
|
||||
unlocked.label.mountFailed = Tentativo di connessione drive fallito
|
||||
unlock.savePassword.delete.confirmation.title = Cancella la password salvata
|
||||
unlock.savePassword.delete.confirmation.header = Vuoi veramente cancellare le password salvate in questo vault?
|
||||
unlock.savePassword.delete.confirmation.content = Le password salvate in questo vault saranno immediatamente cancellate dal sistema di chiavi. Se vuoi salvare nuovamente la tua password, devi sbloccare il tuo vault con l'opzione "Salva password" abilitata.
|
||||
settings.debugMode.label = Modalita' debug *
|
||||
upgrade.version3dropBundleExtension.title = Aggiornamento Vault versione 3 ( Estensione Drop bundle )
|
||||
upgrade.version3to4.title = Aggiornamento Vault da versione 3 a 4
|
||||
upgrade.version4to5.title = Aggiornamento da versione 4 a 5
|
||||
upgrade.version4to5.msg = Questo vault ha bisogno di essere migrato ad un formato piu' recente. Tutti i files criptati saranno aggiornati. Per favore assicurati che la sincronizzazione sia terminata prima di procedere.\n\nNota\: la data di modifica di tutti i files cambiera' alla data/ora attuale del processo.
|
||||
upgrade.version4to5.err.io = Migrazione fallita a causa di una eccezione I/O. Verifica il file di log per i dettagli.
|
||||
settings.port.apply = Apply
|
||||
unlock.label.mountAfterUnlock = Mount Drive
|
||||
unlock.label.revealAfterMount = Reveal Drive
|
||||
@@ -52,11 +52,6 @@ unlocked.label.unmountFailed = 外部出力の排出エラー
|
||||
unlocked.label.statsEncrypted = 暗号化
|
||||
unlocked.label.statsDecrypted = 解読
|
||||
unlocked.ioGraph.yAxis.label = 情報処理量
|
||||
# mac_warnings.fxml
|
||||
macWarnings.windowTitle = 危険-有害でフォルダの%s
|
||||
macWarnings.message = Cryptomatorは、以下のファイルで潜在的に悪意のある改悪されたものを見つけました
|
||||
macWarnings.moreInformationButton = より習得する
|
||||
macWarnings.whitelistButton = フォルダを選択、解読してください
|
||||
# settings.fxml
|
||||
settings.version.label = バージョンの%s
|
||||
settings.checkForUpdates.label = 最新版のチェック
|
||||
@@ -79,21 +74,24 @@ initialize.label.doNotForget = 重要:パスワードを忘れましたら、
|
||||
main.directoryList.remove.confirmation.title = 金庫の削除
|
||||
main.directoryList.remove.confirmation.header = 本当にこの金庫を取り除きたいですか?
|
||||
main.directoryList.remove.confirmation.content = 金庫はリストのみで削除されます。永久に削除するなら、ファイルシステムからファイルを削除してください。
|
||||
upgrade.version3to4.msg = This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding.
|
||||
upgrade.version3to4.err.io = Migration failed due to an I/O Exception. See log file for details.
|
||||
settings.prefGvfsScheme.label = WebDAV Scheme
|
||||
upgrade.version3to4.msg = この金庫は新しいフォーマットに移行する必要があります。暗号化されたフォルダの名前は更新されます。進行する前に同期が完了していることをご確認ください。
|
||||
upgrade.version3to4.err.io = I/O例外のため移行が失敗しました。詳細はログをご確認ください。
|
||||
settings.prefGvfsScheme.label = WebDAVスキーム
|
||||
# upgrade.fxml
|
||||
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
|
||||
initialize.messageLabel.notEmpty = Vault not empty
|
||||
unlock.label.savePassword = Save Password
|
||||
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
|
||||
unlocked.label.mountFailed = Connecting drive failed
|
||||
unlock.savePassword.delete.confirmation.title = Delete Saved Password
|
||||
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
|
||||
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
|
||||
settings.debugMode.label = Debug Mode *
|
||||
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
|
||||
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
|
||||
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
|
||||
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
|
||||
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.
|
||||
upgrade.confirmation.label = はい、同期が完了していることを確認しました。
|
||||
initialize.messageLabel.notEmpty = 金庫が空いていません。
|
||||
unlock.label.savePassword = パスワード保存
|
||||
unlock.errorMessage.unauthenticVersionMac = バージョンMACを認証できません。
|
||||
unlocked.label.mountFailed = ドライブの接続に失敗しました。
|
||||
unlock.savePassword.delete.confirmation.title = 保存されたパスワードを削除
|
||||
unlock.savePassword.delete.confirmation.header = あなたは本当にこの金庫の保存されたパスワードを削除しますか?
|
||||
unlock.savePassword.delete.confirmation.content = この金庫の保存されたパスワードはあなたのシステムキーチェーンから直ちに削除されます。もしまたパスワードを保存したい際には、”パスワード保存”オプションを有効にした上に金庫を解除する必要があります。
|
||||
settings.debugMode.label = デバッグモード
|
||||
upgrade.version3dropBundleExtension.title = 金庫バージョン3アップグレード(Drop Bundle Extension)
|
||||
upgrade.version3to4.title = 金庫バージョン3から4にアップグレード
|
||||
upgrade.version4to5.title = 金庫バージョン4から5にアップグレード
|
||||
upgrade.version4to5.msg = この金庫は新しいフォーマットに移行する必要があります。暗号化されたファイルは更新されます。進行する前に同期が完了していることをご確認ください。\n\n注意:すべてのファイルの変更日は、現在の日付・時刻に変わります。
|
||||
upgrade.version4to5.err.io = I/O例外のため移行が失敗しました。詳細はログをご確認ください。
|
||||
settings.port.apply = 適用
|
||||
unlock.label.mountAfterUnlock = ドライブをマウント
|
||||
unlock.label.revealAfterMount = ドライブを明らかにする
|
||||
@@ -52,11 +52,6 @@ unlocked.label.unmountFailed = 드라이브 추출 실패
|
||||
unlocked.label.statsEncrypted = 암호화
|
||||
unlocked.label.statsDecrypted = 복호화
|
||||
unlocked.ioGraph.yAxis.label = 처리량 (MiB/s)
|
||||
# mac_warnings.fxml
|
||||
macWarnings.windowTitle = 위험 - %s에 손상된 파일
|
||||
macWarnings.message = Cryptomator가 다음 파일들에서 잠재적인 손상 위험을 감지했습니다.
|
||||
macWarnings.moreInformationButton = 더 알아보기
|
||||
macWarnings.whitelistButton = 선택 항목 강제로 암호 풀기
|
||||
# settings.fxml
|
||||
settings.version.label = 버전 %s
|
||||
settings.checkForUpdates.label = 업데이트 확인
|
||||
@@ -96,4 +91,7 @@ upgrade.version3dropBundleExtension.title = 버전 3 보관함 업그레이드 (
|
||||
upgrade.version3to4.title = 보관함 버전 3에서 4로 업그레이드
|
||||
upgrade.version4to5.title = 보관함 버전 4에서 5로 업그레이드
|
||||
upgrade.version4to5.msg = 이 보관함은 새로운 포맷으로 이전되어야 합니다.\n암호화된 파일들은 업데이트 될 것입니다.\n진행하기 전에 동기화가 완료되었는지 확인해주세요.\n\n참고\: 모든 파일의 수정 날짜는 과정 진행 중에 현재 날짜/시간으로 바뀔 것입니다.
|
||||
upgrade.version4to5.err.io = I/O 예외에 의해 마이그레이션 실패. 자세한 사항은 로그 파일을 참조하세요.
|
||||
upgrade.version4to5.err.io = I/O 예외에 의해 마이그레이션 실패. 자세한 사항은 로그 파일을 참조하세요.
|
||||
settings.port.apply = 적용
|
||||
unlock.label.mountAfterUnlock = 드라이브 마운트
|
||||
unlock.label.revealAfterMount = 드라이브 공개
|
||||
@@ -52,11 +52,6 @@ unlocked.label.unmountFailed = Diska izgrūšana neizdevās
|
||||
unlocked.label.statsEncrypted = šifrēts
|
||||
unlocked.label.statsDecrypted = atšifrēts
|
||||
unlocked.ioGraph.yAxis.label = Caurlaidība (MiB/s)
|
||||
# mac_warnings.fxml
|
||||
macWarnings.windowTitle = Bīstami - %s satur bojātu datni
|
||||
macWarnings.message = Cryptomator konstatēja potenciāli ļaunprātīgu bojājumu sekojošām datnēm\:
|
||||
macWarnings.moreInformationButton = Skatīt vairāk
|
||||
macWarnings.whitelistButton = Atšifrēt iezīmēto tāpat
|
||||
# settings.fxml
|
||||
settings.version.label = Versija %s
|
||||
settings.checkForUpdates.label = Meklēt atjauninājumus
|
||||
@@ -69,7 +64,7 @@ tray.menu.open = Atvērt
|
||||
tray.menu.quit = Iziet
|
||||
tray.infoMsg.title = Joprojām darbojās
|
||||
# Fuzzy
|
||||
tray.infoMsg.msg = Cryptomator joprojām darbojās. Iziet var no ikonas.
|
||||
tray.infoMsg.msg = Cryptomator joprojām darbojās. Iziet var no statusa ikonas.
|
||||
tray.infoMsg.msg.osx = Cryptomator is still alive. joprojām darbojās. Iziet var no izvēlnes ikonas.
|
||||
initialize.messageLabel.passwordStrength.0 = Ļoti vāja
|
||||
initialize.messageLabel.passwordStrength.1 = Vāja
|
||||
@@ -85,16 +80,19 @@ upgrade.version3to4.err.io = Migrācija neizdevās dēļ I/O izņēmuma. Sīkāk
|
||||
settings.prefGvfsScheme.label = WebDAV shēma
|
||||
# upgrade.fxml
|
||||
upgrade.confirmation.label = Jā, esmu pārliecinājies, ka sinhronizācija ir pabeigta.
|
||||
initialize.messageLabel.notEmpty = Vault not empty
|
||||
unlock.label.savePassword = Save Password
|
||||
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
|
||||
unlocked.label.mountFailed = Connecting drive failed
|
||||
unlock.savePassword.delete.confirmation.title = Delete Saved Password
|
||||
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
|
||||
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
|
||||
settings.debugMode.label = Debug Mode *
|
||||
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
|
||||
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
|
||||
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
|
||||
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
|
||||
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.
|
||||
initialize.messageLabel.notEmpty = Glabātuve nav tukša
|
||||
unlock.label.savePassword = Saglabāt paroli
|
||||
unlock.errorMessage.unauthenticVersionMac = Nevar autentificēt versijas MAC
|
||||
unlocked.label.mountFailed = Diska pievienošana neizdevās
|
||||
unlock.savePassword.delete.confirmation.title = Dzēst saglabāto paroli
|
||||
unlock.savePassword.delete.confirmation.header = Vai tiešām vēlies dzēst saglabāto paroli šai glabātuvei?
|
||||
unlock.savePassword.delete.confirmation.content = Saglabātā parole nekavējoties tiks izdzēsta. Ja vēlēsies paroli atkārtoti saglabāt, tev būs jāatslēdz glabātuve ar ieslēgtu opciju "Saglabāt paroli".
|
||||
settings.debugMode.label = Atkļūdošanas režīms *
|
||||
upgrade.version3dropBundleExtension.title = Glabātuves 3 versijas atjauninājums (atmet paplašinājumu)
|
||||
upgrade.version3to4.title = Glabātuves versijas 3 uz 4 atjauninājums
|
||||
upgrade.version4to5.title = Glabātuves versijas 4 uz 5 atjauninājums
|
||||
upgrade.version4to5.msg = Šo glabātuvi nepieciešams migrēt uz jaunāku versiju.\nŠifrētās datnes tiks atjauninātas.\nPirms apstiprini, pārliecinies, ka ir beigusies sinhronizācija.\n\nPiezīme\: Visām datnēm modificēšanas datums tiks izmainīts uz šodienas datumu.
|
||||
upgrade.version4to5.err.io = Migrācijas kļīda dēļ I/O izņēmuma. Sīkāku informāciju skaties žurnālā.
|
||||
settings.port.apply = Apply
|
||||
unlock.label.mountAfterUnlock = Mount Drive
|
||||
unlock.label.revealAfterMount = Reveal Drive
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user