Skip to content

Commit

Permalink
Merge branch 'release/0.1.4'
Browse files Browse the repository at this point in the history
# Conflicts:
#	pom.xml
  • Loading branch information
overheadhunter committed Nov 2, 2016
2 parents e4a7c3b + ef4f856 commit e190a9a
Show file tree
Hide file tree
Showing 23 changed files with 1,017 additions and 266 deletions.
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
language: java
sudo: false
sudo: required
jdk:
- oraclejdk8
env:
Expand All @@ -10,6 +10,7 @@ env:
- secure: aLCaSgLfFniEPpiEdvEyFLlak4cTspVE3uqeGFCncPFUyyxPZ0JW+DdyFpvO5DXBa3hr9oS240H6f1T6Eo/J4K5SaKq3gS3yIzbvs2BS5yoCE4hGIZ6yS/70sIhlxvFvujJDT9KPYo8J6KE0w5vqy8BHEMZYBMEDWWvswwrvlqdaoZqe6vaoV1TsOeWeW+2qFdYu5j1KVQgSwOgzMdQuqQVSsrdA1FH+AzmMMbk3QgdGGd1U4MnFStIeG5/YfqVHkUVpZayhYB9yFzUCObT9R5zZ1OtghdOrkX1FRTKbFPAmJouToeFrIqrZEMbaE9PWaajuUZeqL2hQD1s0A+wj65cXjgbQhz4v7Gr0J/+2AU+9N+IRAIguiq6rXtt1HeR3YbBwlxFdwmEgYJjqO7+XFZFNYbr3YPgqbqJbgXpoxeUTdPNdNwckBUEQTTN6fs89Og6wHLDgoZb5niypSKWd/SFCU81FAGQ0mxy41jJOdltxVtG1+UOfb/41PRAzS6br7CpNnaq379kKlMiyOXY4UCWuFgwW4KhlUx0dgidqi2etcYrDZhZbguHmfLRfumEQ8nCp8LJ5FwJWlkmJhE8hFTu3sGmVUl06Ly1gybMPazev8hYjyr3vaexmek7qeqDtNT6n8L96qZkResjFI2pJmzZaNIg2yK92ZS/5v073OgM= # MAVEN_OSSRH_PASSWORD
- secure: JUBj12rP7sEsNp8R3o9Mjwl7HCYKQan58CZ1WDm7L2MteFRDBJr625P4fk4cQOTjR6fb3jiogCD7dqkHoGJQlvi2ReQJLXKBhy3Bqtnzksf4c1By9bLB5NYH6MQV1FFazzAjjPjGlQYJB+kUx+pQ8vxMJC5yzp6vpKWu3vTobEFNtuFAWZq7qM91VJBUc8z+k1awas9vqgDlqWxH+K05L2c+tpnnmqXk9/HN9Z4akkKB++oACenE+w+D9Snyiif9WyhVR3+ZcMtL44YAQDabl6LlrTdM4afNaPcwgOdFuxL7GCZyIMgMP26O8JquK4ZtE2b/ZMz5h0jtE+r6M0E+yVAN+kG7UviNd9kKItiRiokDsaYeNCWVPHndGBtw6GU5GFNJTDhEb/oeqzclI/PaFHXA4O/o4A9N+nrzb28xWaihAM/NymVOE1iNNQfyNqPb9fjsMntNOTDT/sLH3tTJ62nvVPpurUXVV0+jbSrE20xclOZ1xBbMztQwya4EB/0fS+raCiR5spXHTNHpmSp2ubKAuo6V4AUXQXk6LHxiiIvcYSRYVgnBeOcreuDYv7+09xeIejxVcSzh7Nz7aK/0Fkq42ALYs/cDOq0mJGwoJ4yC7vlMj6GQNwZtCP+bzdGM3+cjTcD2F997Hf75lEVeYXK2oNE3/ycSQjdYlc3wTl0= #COVERITY_SCAN_TOKEN
install:
- sudo apt-get install haveged
- mvn dependency:go-offline -Pdependency-check
- mvn dependency:go-offline -Pcoverage
- mvn source:help javadoc:help dependency:go-offline -Prelease
Expand All @@ -33,7 +34,6 @@ addons:
branch_pattern: release.*
before_deploy:
- "if ! gpg --list-secret-keys 34C80F11; then gpg --import 34C80F11.gpg; fi"
- "ls -la target"
deploy:
- provider: script # SNAPSHOTS
script: mvn clean deploy -DskipTests -Prelease --settings settings.xml
Expand All @@ -56,6 +56,7 @@ deploy:
- "target/dependency-list.txt"
- "target/*.jar"
skip_cleanup: true
prerelease: true
on:
repo: cryptomator/cryptofs
tags: true
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.cryptomator</groupId>
<artifactId>cryptofs</artifactId>
<version>0.1.3</version>
<version>0.1.4</version>
<name>Cryptomator Crypto Filesystem</name>
<description>This library provides the Java filesystem provider used by Cryptomator.</description>
<url>https://github.com/cryptomator/cryptofs</url>
Expand Down Expand Up @@ -61,7 +61,7 @@
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>cryptolib</artifactId>
<version>1.0.2</version>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
Expand All @@ -71,7 +71,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
<version>20.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.cryptomator.cryptofs;

interface BiConsumerThrowingException<A, B, E extends Exception> {

void accept(A a, B b) throws E;

}
135 changes: 135 additions & 0 deletions src/main/java/org/cryptomator/cryptofs/CopyAndMoveOperations.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package org.cryptomator.cryptofs;

import static java.nio.file.StandardCopyOption.ATOMIC_MOVE;
import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static java.nio.file.StandardOpenOption.CREATE_NEW;
import static java.nio.file.StandardOpenOption.READ;
import static java.nio.file.StandardOpenOption.WRITE;

import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.AtomicMoveNotSupportedException;
import java.nio.file.CopyOption;
import java.nio.file.DirectoryStream;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.spi.FileSystemProvider;
import java.util.EnumSet;
import java.util.Optional;

import javax.inject.Inject;

import org.apache.commons.lang3.ArrayUtils;

@PerProvider
class CopyAndMoveOperations {

@Inject
public CopyAndMoveOperations() {
}

public void copy(CryptoPath source, CryptoPath target, CopyOption... options) throws IOException {
if (source.equals(target)) {
return;
}
if (pathsBelongToSameFileSystem(source, target)) {
source.getFileSystem().copy(source, target, options);
} else {
Optional<BasicFileAttributes> sourceAttrs = attributes(source);
Optional<BasicFileAttributes> targetAttrs = attributes(target);
if (!sourceAttrs.isPresent()) {
throw new NoSuchFileException(source.toUri().toString());
}
if (targetAttrs.isPresent()) {
if (ArrayUtils.contains(options, REPLACE_EXISTING)) {
provider(target).delete(target);
} else {
throw new FileAlreadyExistsException(target.toUri().toString());
}
}
if (sourceAttrs.get().isDirectory()) {
provider(target).createDirectory(target);
} else {
try (FileChannel sourceChannel = provider(source).newFileChannel(source, EnumSet.of(READ)); //
FileChannel targetChannel = provider(target).newFileChannel(target, EnumSet.of(CREATE_NEW, WRITE))) {
sourceChannel.transferTo(0, sourceChannel.size(), targetChannel);
}
}
if (ArrayUtils.contains(options, COPY_ATTRIBUTES)) {
BasicFileAttributeView targetAttrView = provider(target).getFileAttributeView(target, BasicFileAttributeView.class);
targetAttrView.setTimes(sourceAttrs.get().lastModifiedTime(), sourceAttrs.get().lastAccessTime(), sourceAttrs.get().creationTime());
}
}
}

private FileSystemProvider provider(CryptoPath path) {
return path.getFileSystem().provider();
}

public void move(CryptoPath source, CryptoPath target, CopyOption... options) throws IOException {
if (source.equals(target)) {
return;
}
if (pathsBelongToSameFileSystem(source, target)) {
source.getFileSystem().move(source, target, options);
} else {
if (ArrayUtils.contains(options, ATOMIC_MOVE)) {
throw new AtomicMoveNotSupportedException(source.toUri().toString(), target.toUri().toString(), "Move of encrypted file to different FileSystem");
}
if (isNonEmptyDirectory(source)) {
throw new IOException("Can not move non empty directory to different FileSystem");
}
boolean success = false;
try {
copy(source, target, addCopyAttributesTo(options));
success = true;
} finally {
if (!success) {
// do a best effort to clean a partially copied file
try {
provider(target).deleteIfExists(target);
} catch (IOException e) {
// ignore
}
}
}
provider(source).deleteIfExists(source);
}
}

private boolean pathsBelongToSameFileSystem(CryptoPath source, CryptoPath target) {
return source.getFileSystem() == target.getFileSystem();
}

private boolean isNonEmptyDirectory(CryptoPath source) throws IOException {
Optional<BasicFileAttributes> sourceAttrs = attributes(source);
if (!sourceAttrs.map(BasicFileAttributes::isDirectory).orElse(false)) {
return false;
}
try (DirectoryStream<Path> contents = provider(source).newDirectoryStream(source, ignored -> true)) {
return contents.iterator().hasNext();
}
}

private Optional<BasicFileAttributes> attributes(CryptoPath path) {
try {
return Optional.of(provider(path).readAttributes(path, BasicFileAttributes.class));
} catch (IOException e) {
return Optional.empty();
}
}

private CopyOption[] addCopyAttributesTo(CopyOption[] options) {
CopyOption[] result = new CopyOption[options.length + 1];
for (int i = 0; i < options.length; i++) {
result[i] = options[i];
}
result[options.length] = COPY_ATTRIBUTES;
return result;
}

}
14 changes: 11 additions & 3 deletions src/main/java/org/cryptomator/cryptofs/CryptoDirectoryStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
*******************************************************************************/
package org.cryptomator.cryptofs;

import static org.cryptomator.cryptofs.FinallyUtils.guaranteeInvocationOf;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
Expand All @@ -16,6 +18,7 @@
import java.nio.file.Path;
import java.util.Iterator;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand All @@ -38,8 +41,11 @@ class CryptoDirectoryStream implements DirectoryStream<Path> {
private final FileNameCryptor filenameCryptor;
private final LongFileNameProvider longFileNameProvider;
private final DirectoryStream.Filter<? super Path> filter;
private final Consumer<CryptoDirectoryStream> onClose;

public CryptoDirectoryStream(Directory ciphertextDir, Path cleartextDir, FileNameCryptor filenameCryptor, LongFileNameProvider longFileNameProvider, DirectoryStream.Filter<? super Path> filter) throws IOException {
public CryptoDirectoryStream(Directory ciphertextDir, Path cleartextDir, FileNameCryptor filenameCryptor, LongFileNameProvider longFileNameProvider, DirectoryStream.Filter<? super Path> filter,
Consumer<CryptoDirectoryStream> onClose) throws IOException {
this.onClose = onClose;
this.directoryId = ciphertextDir.dirId;
this.ciphertextDirStream = Files.newDirectoryStream(ciphertextDir.path, p -> true);
LOG.trace("OPEN " + directoryId);
Expand Down Expand Up @@ -101,8 +107,10 @@ private boolean isAcceptableByFilter(Path path) {

@Override
public void close() throws IOException {
ciphertextDirStream.close();
LOG.trace("CLOSE " + directoryId);
guaranteeInvocationOf( //
() -> ciphertextDirStream.close(), //
() -> onClose.accept(this), //
() -> LOG.trace("CLOSE " + directoryId));
}

}
Loading

0 comments on commit e190a9a

Please sign in to comment.