Skip to content
This repository was archived by the owner on Feb 26, 2025. It is now read-only.

Commit a9d4da4

Browse files
authored
Merge pull request #2 from TimWolters/3188-make-resolve-more-robust
make relative S3Path.resolve correct
2 parents 4fe1a64 + 68a5473 commit a9d4da4

File tree

3 files changed

+84
-12
lines changed

3 files changed

+84
-12
lines changed

Diff for: src/main/java/com/upplication/s3fs/S3Path.java

+27-12
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
package com.upplication.s3fs;
22

3-
import com.google.common.base.*;
4-
import com.google.common.collect.ImmutableList;
5-
import com.google.common.collect.Lists;
6-
import com.upplication.s3fs.attribute.S3BasicFileAttributes;
3+
import static com.google.common.collect.Iterables.concat;
4+
import static java.lang.String.format;
75

86
import java.io.File;
97
import java.io.IOException;
108
import java.io.UnsupportedEncodingException;
119
import java.net.URI;
1210
import java.net.URL;
1311
import java.net.URLDecoder;
14-
import java.nio.file.*;
12+
import java.nio.file.LinkOption;
13+
import java.nio.file.Path;
14+
import java.nio.file.WatchEvent;
15+
import java.nio.file.WatchKey;
16+
import java.nio.file.WatchService;
1517
import java.util.Iterator;
1618
import java.util.List;
1719

18-
import static com.google.common.collect.Iterables.*;
19-
import static java.lang.String.format;
20+
import com.google.common.base.Preconditions;
21+
import com.google.common.base.Splitter;
22+
import com.google.common.collect.ImmutableList;
23+
import com.google.common.collect.Lists;
24+
import com.upplication.s3fs.attribute.S3BasicFileAttributes;
2025

2126
public class S3Path implements Path {
2227

@@ -353,27 +358,37 @@ public Path normalize() {
353358

354359
@Override
355360
public Path resolve(Path other) {
361+
String otherUri = "";
356362
if (other.isAbsolute()) {
357-
Preconditions.checkArgument(other instanceof S3Path, "other must be an instance of %s", S3Path.class.getName());
363+
Preconditions.checkArgument(other instanceof S3Path, "other must be an instance of %s or be relative", S3Path.class.getName());
358364
return other;
365+
} else if (!(other instanceof S3Path)) {
366+
int nameCount = other.getNameCount();
367+
for (int i = 0; i < nameCount; i++) {
368+
if (i > 0)
369+
otherUri += PATH_SEPARATOR;
370+
otherUri += other.getName(i);
371+
}
372+
} else {
373+
S3Path otherS3Path = (S3Path) other;
374+
otherUri = otherS3Path.uri;
359375
}
360376

361-
S3Path otherS3Path = (S3Path) other;
362377
StringBuilder pathBuilder = new StringBuilder();
363378

364379
if (this.isAbsolute()) {
365380
pathBuilder.append(PATH_SEPARATOR + this.fileStore.name() + PATH_SEPARATOR);
366381
}
367382
pathBuilder.append(this.uri);
368-
if (!otherS3Path.uri.isEmpty())
369-
pathBuilder.append(PATH_SEPARATOR + otherS3Path.uri);
383+
if (!otherUri.isEmpty())
384+
pathBuilder.append(PATH_SEPARATOR + otherUri);
370385

371386
return new S3Path(this.fileSystem, pathBuilder.toString());
372387
}
373388

374389
@Override
375390
public Path resolve(String other) {
376-
return resolve(new S3Path(this.getFileSystem(), other));
391+
return resolve(new S3Path(this.getFileSystem(), URI.create(other).getPath()));
377392
}
378393

379394
@Override

Diff for: src/test/java/com/upplication/s3fs/Path/S3PathTest.java

+54
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.upplication.s3fs.Path;
22

3+
import com.upplication.s3fs.AmazonS3Factory;
34
import com.upplication.s3fs.S3FileSystem;
45
import com.upplication.s3fs.S3FileSystemProvider;
56
import com.upplication.s3fs.S3Path;
@@ -9,8 +10,10 @@
910
import org.junit.Test;
1011

1112
import java.io.IOException;
13+
import java.net.URI;
1214
import java.nio.file.FileSystems;
1315
import java.nio.file.Path;
16+
import java.nio.file.Paths;
1417
import java.nio.file.WatchEvent;
1518
import java.util.HashMap;
1619

@@ -232,4 +235,55 @@ public void registerWatchService() throws IOException {
232235
S3Path path = forPath("/buck/file");
233236
path.register(null, new WatchEvent.Kind<?>[0], new WatchEvent.Modifier[0]);
234237
}
238+
@Test
239+
public void testResolve() throws IOException {
240+
S3FileSystem fileSystem2 = null;
241+
try {
242+
HashMap<String, String> environments = new HashMap<>();
243+
environments.put(AmazonS3Factory.ACCESS_KEY, "accesskey");
244+
environments.put(AmazonS3Factory.SECRET_KEY, "secretaccesskey");
245+
246+
fileSystem2 = (S3FileSystem) FileSystems.newFileSystem(URI.create("s3://accesskey:[email protected]/bucket"), environments);
247+
248+
//good
249+
S3Path parent = (S3Path) fileSystem2.provider().getPath(URI.create("s3://accesskey:[email protected]/bucket"));
250+
S3Path child = (S3Path) fileSystem2.provider().getPath(URI.create("s3://accesskey:[email protected]/bucket/rabbit"));
251+
S3Path resolved = (S3Path) parent.resolve(child);
252+
253+
assertEquals(child, resolved);
254+
255+
resolved = (S3Path) parent.resolve("s3://accesskey:[email protected]/bucket/rabbit");
256+
assertEquals(child, resolved);
257+
258+
resolved = (S3Path) parent.resolve("rabbit");
259+
assertEquals(child, resolved);
260+
261+
resolved = (S3Path) parent.resolve(Paths.get("rabbit")); //unixPath
262+
assertEquals(child, resolved);
263+
264+
resolved = (S3Path) parent.resolve(Paths.get("./rabbit")); //unixPath
265+
assertEquals("s3://accesskey:[email protected]/bucket/./rabbit", resolved.toString());
266+
267+
resolved = (S3Path) parent.resolve(Paths.get("./rabbit in space")); //unixPath
268+
assertEquals("s3://accesskey:[email protected]/bucket/./rabbit%20in%20space", resolved.toString());
269+
270+
try {
271+
parent.resolve(Paths.get("/tmp"));
272+
fail("expect IllegalArgumentException");
273+
} catch (IllegalArgumentException e) {
274+
//ignore
275+
assertEquals("other must be an instance of com.upplication.s3fs.S3Path or be relative", e.getMessage());
276+
}
277+
278+
//bad
279+
S3Path parent2 = fileSystem2.getPath("s3://accesskey:[email protected]/bucket");
280+
S3Path child2 = fileSystem2.getPath("s3://accesskey:[email protected]/bucket/rabbit");
281+
S3Path resolved2 = (S3Path) parent2.resolve(child2);
282+
assertEquals("s3:/accesskey:[email protected]/bucket/s3:/accesskey:[email protected]/bucket/rabbit", resolved2.toString());
283+
284+
} finally {
285+
if (fileSystem2 != null)
286+
fileSystem2.close();
287+
}
288+
}
235289
}

Diff for: src/test/java/com/upplication/s3fs/Path/ToUriTest.java

+3
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ public void toUriRelative() {
7777

7878
S3Path path = new S3Path(fileSystem, "bla");
7979
assertEquals(URI.create("bla"), path.toUri());
80+
81+
S3Path withSpaces = new S3Path(fileSystem, "with space");
82+
assertEquals(URI.create("with%20space"), withSpaces.toUri());
8083
}
8184

8285
@Test

0 commit comments

Comments
 (0)