mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-22 20:51:27 +00:00
Code simplification
This commit is contained in:
@@ -10,9 +10,6 @@ package org.cryptomator.io;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* TODO this probably doesn't belong into this maven module, but it is used by various filesystem layers.
|
||||
*/
|
||||
public final class ByteBuffers {
|
||||
|
||||
private ByteBuffers() {
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package org.cryptomator.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.cryptomator.filesystem.File;
|
||||
import org.cryptomator.filesystem.WritableFile;
|
||||
|
||||
public final class FileContents {
|
||||
|
||||
public static final FileContents UTF_8 = FileContents.withCharset(StandardCharsets.UTF_8);
|
||||
|
||||
private final Charset charset;
|
||||
|
||||
private FileContents(Charset charset) {
|
||||
this.charset = charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the whole content from the given file.
|
||||
*
|
||||
* @param file File whose content should be read.
|
||||
* @return The file's content interpreted in this FileContents' charset.
|
||||
*/
|
||||
public String readContents(File file) {
|
||||
try (Reader reader = Channels.newReader(file.openReadable(), charset.newDecoder(), -1)) {
|
||||
return IOUtils.toString(reader);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the string into the file encoded with this FileContents' charset.
|
||||
* This methods replaces any previously existing content, i.e. the string will be the sole content.
|
||||
*
|
||||
* @param file File whose content should be written.
|
||||
* @param content The new content.
|
||||
*/
|
||||
public void writeContents(File file, String content) {
|
||||
try (WritableFile writable = file.openWritable()) {
|
||||
writable.truncate();
|
||||
writable.write(charset.encode(content));
|
||||
}
|
||||
}
|
||||
|
||||
public static FileContents withCharset(Charset charset) {
|
||||
return new FileContents(charset);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package org.cryptomator.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.cryptomator.filesystem.File;
|
||||
import org.cryptomator.filesystem.ReadableFile;
|
||||
import org.cryptomator.filesystem.WritableFile;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.theories.DataPoints;
|
||||
import org.junit.experimental.theories.Theories;
|
||||
import org.junit.experimental.theories.Theory;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
@RunWith(Theories.class)
|
||||
public class FileContentsTest {
|
||||
|
||||
@DataPoints
|
||||
public static final Iterable<Charset> CHARSETS = Arrays.asList(StandardCharsets.UTF_8, StandardCharsets.US_ASCII, StandardCharsets.UTF_16);
|
||||
|
||||
@DataPoints
|
||||
public static final Iterable<String> TEST_CONTENTS = Arrays.asList("hello world", "hellö wörld", "");
|
||||
|
||||
@Theory
|
||||
public void testReadAll(Charset charset, String testString) {
|
||||
Assume.assumeTrue(charset.newEncoder().canEncode(testString));
|
||||
|
||||
ByteBuffer testContent = ByteBuffer.wrap(testString.getBytes(charset));
|
||||
File file = Mockito.mock(File.class);
|
||||
ReadableFile readable = Mockito.mock(ReadableFile.class);
|
||||
Mockito.when(file.openReadable()).thenReturn(readable);
|
||||
Mockito.when(readable.read(Mockito.any(ByteBuffer.class))).then(invocation -> {
|
||||
ByteBuffer target = invocation.getArgumentAt(0, ByteBuffer.class);
|
||||
if (testContent.hasRemaining()) {
|
||||
return ByteBuffers.copy(testContent, target);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
});
|
||||
|
||||
String contentsRead = FileContents.withCharset(charset).readContents(file);
|
||||
Assert.assertEquals(testString, contentsRead);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testWriteAll(Charset charset, String testString) {
|
||||
Assume.assumeTrue(charset.newEncoder().canEncode(testString));
|
||||
|
||||
ByteBuffer testContent = ByteBuffer.allocate(100);
|
||||
File file = Mockito.mock(File.class);
|
||||
WritableFile writable = Mockito.mock(WritableFile.class);
|
||||
Mockito.when(file.openWritable()).thenReturn(writable);
|
||||
Mockito.doAnswer(invocation -> {
|
||||
testContent.clear();
|
||||
return null;
|
||||
}).when(writable).truncate();
|
||||
Mockito.when(writable.write(Mockito.any(ByteBuffer.class))).then(invocation -> {
|
||||
ByteBuffer source = invocation.getArgumentAt(0, ByteBuffer.class);
|
||||
if (testContent.hasRemaining()) {
|
||||
return ByteBuffers.copy(source, testContent);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
});
|
||||
|
||||
FileContents.withCharset(charset).writeContents(file, testString);
|
||||
Assert.assertArrayEquals(testString.getBytes(charset), Arrays.copyOf(testContent.array(), testContent.position()));
|
||||
}
|
||||
|
||||
@Test(expected = UncheckedIOException.class)
|
||||
public void testIOExceptionDuringRead() {
|
||||
File file = Mockito.mock(File.class);
|
||||
Mockito.when(file.openReadable()).thenAnswer(invocation -> {
|
||||
throw new IOException("failed");
|
||||
});
|
||||
|
||||
FileContents.UTF_8.readContents(file);
|
||||
}
|
||||
|
||||
@Test(expected = UncheckedIOException.class)
|
||||
public void testUncheckedIOExceptionDuringRead() {
|
||||
File file = Mockito.mock(File.class);
|
||||
Mockito.when(file.openReadable()).thenThrow(new UncheckedIOException(new IOException("failed")));
|
||||
|
||||
FileContents.UTF_8.readContents(file);
|
||||
}
|
||||
|
||||
@Test(expected = UncheckedIOException.class)
|
||||
public void testUncheckedIOExceptionDuringWrite() {
|
||||
File file = Mockito.mock(File.class);
|
||||
Mockito.when(file.openWritable()).thenThrow(new UncheckedIOException(new IOException("failed")));
|
||||
|
||||
FileContents.UTF_8.writeContents(file, "hello world");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -71,21 +71,9 @@ class CryptoFolder extends CryptoNode implements Folder {
|
||||
}
|
||||
|
||||
protected Optional<String> getDirectoryId() {
|
||||
if (directoryId.get() != null) {
|
||||
return Optional.of(directoryId.get());
|
||||
}
|
||||
if (physicalFile().isPresent()) {
|
||||
File dirFile = physicalFile().get();
|
||||
if (dirFile.exists()) {
|
||||
try (Reader reader = Channels.newReader(dirFile.openReadable(), UTF_8.newDecoder(), -1)) {
|
||||
directoryId.set(IOUtils.toString(reader));
|
||||
return Optional.of(directoryId.get());
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
return Optional.ofNullable(LazyInitializer.initializeLazily(directoryId, () -> {
|
||||
return physicalFile().filter(File::exists).map(FileContents.UTF_8::readContents).orElse(null);
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -156,11 +144,7 @@ class CryptoFolder extends CryptoNode implements Folder {
|
||||
if (parent.file(name).exists()) {
|
||||
throw new UncheckedIOException(new FileAlreadyExistsException(toString()));
|
||||
}
|
||||
try (Writer writer = Channels.newWriter(dirFile.openWritable(), UTF_8.newEncoder(), -1)) {
|
||||
writer.write(directoryId.get());
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
FileContents.UTF_8.writeContents(dirFile, directoryId.get());
|
||||
dir.create();
|
||||
}
|
||||
|
||||
|
||||
@@ -8,22 +8,16 @@
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.filesystem.shortening;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.io.Writer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import org.apache.commons.codec.binary.Base32;
|
||||
import org.apache.commons.codec.binary.BaseNCodec;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.cryptomator.filesystem.File;
|
||||
import org.cryptomator.filesystem.Folder;
|
||||
import org.cryptomator.io.FileContents;
|
||||
|
||||
class FilenameShortener {
|
||||
|
||||
@@ -64,11 +58,7 @@ class FilenameShortener {
|
||||
final File mappingFile = mappingFile(shortName);
|
||||
if (!mappingFile.exists()) {
|
||||
mappingFile.parent().get().create();
|
||||
try (Writer writer = Channels.newWriter(mappingFile.openWritable(), UTF_8.newEncoder(), -1)) {
|
||||
writer.write(longName);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
FileContents.UTF_8.writeContents(mappingFile, longName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,11 +72,7 @@ class FilenameShortener {
|
||||
if (!mappingFile.exists()) {
|
||||
throw new UncheckedIOException(new FileNotFoundException("Mapping file not found " + mappingFile));
|
||||
} else {
|
||||
try (Reader reader = Channels.newReader(mappingFile.openReadable(), UTF_8.newDecoder(), -1)) {
|
||||
return IOUtils.toString(reader);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
return FileContents.UTF_8.readContents(mappingFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user