JimfsPath.resolve can accept Path instance other than JimfsPath
altair2010 opened this issue · 2 comments
altair2010 commented
JimfsPath.resolve(Path)
doesn't accept Path instance if it's not a JimfsPath one, even if the given Path is a relative one.
When the given Path is not absoute why not to convert to string and parse if to create a JimfsPath ?
something like this
public JimfsPath resolve(Path other) {
if(!other.isAbsolute()) {
// Convert other in a JimfsPath using String representation
other = pathService.parsePath(other.toString());
}
// Start of existing code
JimfsPath otherPath = checkPath(other);
if (otherPath == null) {
throw new ProviderMismatchException(other.toString());
}
...
}
My use case is
public void productionCode(Path rootPath) {
...
Path relPath = Paths.get("xxx", "yyy", "zzz");
...
Path fullPath = rootPath.resolve(relPath);
...
}
@Test
public void test() {
// Given
FileSystem fileSystem = Jimfs.newFileSystem();
Path rootPath = fileSystem.getPath("input").toAbsolutePath();
// When
productionCode(rootPath);
}
I see discussion on #12, i understand the limitation of JimfsPath.resolve(Path)
for absolute path, but resolving relative path can be done (IMO)
- using toString() and parsePath
- using Path.iterator() to retrive all part of the path
JakeWharton commented
This behavior is consistent with the Java-provided filesystems (default, zip, etc.) so I am against this change.
$ jshell
| Welcome to JShell -- Version 14.0.2
| For an introduction type: /help intro
jshell> FileSystems.newFileSystem(URI.create("jar:file:/Users/jw/test.zip"), Map.of())
$1 ==> /Users/jw/test.zip
jshell> $1.getPath("./relative.txt")
$2 ==> ./relative.txt
jshell> Paths.get("/Users/jw").resolve($2)
| Exception java.nio.file.ProviderMismatchException
| at UnixPath.toUnixPath (UnixPath.java:198)
| at UnixPath.resolve (UnixPath.java:410)
| at UnixPath.resolve (UnixPath.java:43)
| at (#3:1)
jshell> Paths.get("/Users/jw").resolve($2.toString())
$3 ==> /Users/jw/./relative.txt
cgdecker commented
In addition to what Jake said about the behavior being consistent with the Java-provided filesystems:
- I would argue that your code is incorrect usage of the APIs (the
Path relPath = Paths.get("xxx", "yyy", "zzz");
line specifically); since yourproductionCode
method accepts aPath
, the correct way to create aPath
that you intend to use withrootPath
would berootPath.getFileSystem().getPath("xxx", "yyy", "zzz")
. If you do that, there's no file system mismatch issue. - It doesn't make sense in general to try to resolve a
Path
from one file system against aPath
from another given that file systems may have differing semantics. For example, what would you expect to happen if you attempt to resolve UNIX-likePath
"foo\bar\baz" (a single filename) against a Windows file system? Different people or different situations might expect different things to happen, and it doesn't really make sense for each file system implementation to have to attempt to deal with any possible implementation ofPath
it might be given. This is more just my opinion on why the existing file systems don't attempt to deal with this and why we don't want to either.