From 492efbc5ad78ab3ed06596ba5ec23d321a042ba2 Mon Sep 17 00:00:00 2001 From: Jurjen Stellingwerff Date: Mon, 1 Jul 2019 15:10:12 +0200 Subject: [PATCH] Implement directory copy with similar semantics as nio2. --- .../s3fs/S3FileSystemProvider.java | 37 ++++++++++--------- .../s3fs/FileSystemProvider/CopyTest.java | 28 +++++++++++++- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/upplication/s3fs/S3FileSystemProvider.java b/src/main/java/com/upplication/s3fs/S3FileSystemProvider.java index 77aca37..84414d2 100644 --- a/src/main/java/com/upplication/s3fs/S3FileSystemProvider.java +++ b/src/main/java/com/upplication/s3fs/S3FileSystemProvider.java @@ -398,28 +398,31 @@ public void copy(Path source, Path target, CopyOption... options) throws IOExcep S3Path s3Source = toS3Path(source); S3Path s3Target = toS3Path(target); - // TODO: implements support for copying directories - - Preconditions.checkArgument(!Files.isDirectory(source), "copying directories is not yet supported: %s", source); - Preconditions.checkArgument(!Files.isDirectory(target), "copying directories is not yet supported: %s", target); ImmutableSet actualOptions = ImmutableSet.copyOf(options); verifySupportedOptions(EnumSet.of(StandardCopyOption.REPLACE_EXISTING), actualOptions); - if (exists(s3Target) && !actualOptions.contains(StandardCopyOption.REPLACE_EXISTING)) { - throw new FileAlreadyExistsException(format("target already exists: %s", target)); + if (exists(s3Target)) { + if (!actualOptions.contains(StandardCopyOption.REPLACE_EXISTING)) { + throw new FileAlreadyExistsException(format("target already exists: %s", target)); + } + delete(s3Target); } - String bucketNameOrigin = s3Source.getFileStore().name(); - String keySource = s3Source.getKey(); - String bucketNameTarget = s3Target.getFileStore().name(); - String keyTarget = s3Target.getKey(); - s3Source.getFileSystem() - .getClient().copyObject( - bucketNameOrigin, - keySource, - bucketNameTarget, - keyTarget); + if (Files.isDirectory(source)) { + createDirectory(s3Target); + } else { + String bucketNameOrigin = s3Source.getFileStore().name(); + String keySource = s3Source.getKey(); + String bucketNameTarget = s3Target.getFileStore().name(); + String keyTarget = s3Target.getKey(); + s3Source.getFileSystem() + .getClient().copyObject( + bucketNameOrigin, + keySource, + bucketNameTarget, + keyTarget); + } } @Override @@ -634,4 +637,4 @@ public Cache getCache() { public void setCache(Cache cache) { this.cache = cache; } -} \ No newline at end of file +} diff --git a/src/test/java/com/upplication/s3fs/FileSystemProvider/CopyTest.java b/src/test/java/com/upplication/s3fs/FileSystemProvider/CopyTest.java index 17dd234..2ae9b6a 100644 --- a/src/test/java/com/upplication/s3fs/FileSystemProvider/CopyTest.java +++ b/src/test/java/com/upplication/s3fs/FileSystemProvider/CopyTest.java @@ -16,6 +16,7 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; import static org.mockito.Mockito.*; public class CopyTest extends S3UnitTestBase { @@ -91,6 +92,31 @@ public void copyAlreadyExists() throws IOException { s3fsProvider.copy(file, fileDest); } + @Test + public void copyDirectory() throws IOException { + final String content = "sample-content"; + // fixtures + AmazonS3ClientMock client = AmazonS3MockFactory.getAmazonClientMock(); + client.bucket("bucketA").dir("dir1").file("dir1/file", content.getBytes()); + FileSystem fs = createNewS3FileSystem(); + Path dir1 = fs.getPath("/bucketA", "dir1"); + Path file1 = fs.getPath("/bucketA", "dir1", "file"); + Path dir2 = fs.getPath("/bucketA", "dir2"); + Path file2 = fs.getPath("/bucketA", "dir2", "file"); + // assert + assertTrue(Files.exists(dir1)); + assertTrue(Files.exists(file1)); + assertTrue(Files.isDirectory(dir1)); + assertTrue(Files.isRegularFile(file1)); + assertFalse(Files.exists(dir2)); + assertFalse(Files.exists(file2)); + // act + s3fsProvider.copy(dir1, dir2); + assertTrue(Files.exists(dir2)); + assertTrue(Files.isDirectory(dir2)); + assertFalse(Files.exists(file2)); + } + /** * create a new file system for s3 scheme with fake credentials * and global endpoint @@ -106,4 +132,4 @@ private S3FileSystem createNewS3FileSystem() throws IOException { } } -} \ No newline at end of file +}