abstract paths
Alan Bateman
Alan.Bateman at Sun.COM
Wed Jul 23 03:00:12 PDT 2008
Alan Snyder wrote:
> I'll try to respond to all the comments at once, since they seem to be
> related.
>
> What I have in mind when I say abstract path (I'll call it
> AbstractPath for now, even though the name is already taken) is a type
> whose attributes are (1) a sequence of Strings, (2) an optional String
> representing a Root, (3) a boolean indicating whether the path is
> absolute or relative. There would need to be a way of constructing an
> AbstractPath from these attributes as separate objects (this is not
> the same as parsing a single string). There would need to be a method
> on Path that directly converts a bound Path to an AbstractPath,
> preserving the interpretation of the Path, such as whether it is
> absolute or relative (i.e., not necessarily just unparsing and parsing
> it). There should probably be a method on a FileSystem that takes an
> AbstractPath and returns a bound Path, again, preserving the original
> interpretation rather than unparsing and parsing.
>
> I would expect the following code
>
> Path p1; // already obtained from somewhere
> AbstractPath a = p1.toAbstractPath();
> FileSystem fs = p1.getFileSystem();
> Path p2 = fs.bind(a);
Maybe the best thing is to try it out. As it doesn't require anything
special in the java.nio.file package to prototype this then maybe you
could try it and send back your experiences. The following will do the
conversion you are looking for (as I mentioned in a previous mail this
isn't as efficient as it could be but should be good enough to try).
private final String root;
private final String[] names;
private final boolean isAbsolute;
AbstractPath(Path path) {
this.root = (path.getRoot() != null) ? path.getRoot().toString() :
null;
int count = path.getNameCount();
this.names = new String[count];
for (int i=0; i<count; i++) {
this.names[i] = path.getName(i).toString();
}
this.isAbsolute = path.isAbsolute();
}
Path bind(FileSystem fs) {
Path result = (root != null) ? fs.getPath(root) : null;
for (String name: names) {
result = (result == null) ? fs.getPath(name) :
result.resolve(name);
}
return result;
}
>
> to result in p1.equals(p2) being true.
Unfortunately, you couldn't guarantee this with a round trip as the
conversion to a String may cause the platform representation to be lost.
>
> I would expect the methods I listed in my previous email to work on
> AbstractPaths without using any provider-dependent code.
In that case, equals, compareTo, startsWith, and endsWith would be
String operations and so would behave differently to the equivalent
methods defined by Path.
>
> I would expect that the methods on AbstractPaths would mirror the
> equivalent methods on the bound Paths. (If I remember my college math,
> the mapping is a homeomorphism. :-) ) There may be cases where an
> operation that the bound Path can do (such as resolve using a relative
> path having a root) is either rejected by AbstractPath or does
> something different. I don't see that as a problem, but I'm not sure I
> understand enough about possible provider dependent behaviors.
You could implement resolve for two cases: (i) the given AbstractPath is
absolute in which case the result is the given AbstractPath, and (ii)
the given AbstractPath does not have a root component in which case this
is a simply join. I don't think other cases are feasible. Relativization
is likely to be only feasible for limited cases too.
>
> I would expect AbstractPaths to interoperate with bound Paths wherever
> that makes sense. In particular, it should work in the simple cases,
> such as passing a relative, rootless AbstractPath as a parameter to
> resolve() on a bound Path. (In current cases of interoperation between
> Paths from different providers, an AbstractPath would be the ideal
> intermediate form, would it not?)
As I mentioned previously, we don't currently have a good solution on
how to convert a path from a file system to an "equivalent" path in a
different type of file system. Converting to Strings, while not ideal,
is probably good enough for most needs.
>
> One place where I would use AbstractPaths is in situations where I
> want to make sure my code does not access the actual file system. For
> a file catalog, I might create a subclass of (my) AbstractPath that
> can return file metadata (from the catalog). The file catalog program
> needs to serialize AbstractPaths when writing the catalog, but when it
> runs, it should not need to be doing any parsing of paths.
>
> Hopefully, it is now obvious that "/foo" is not an AbstractPath, it is
> a string. When an AbstractPath is created, the absolute/relative
> attribute must be specified.
>
> (It sounds like the "My Documents" example would be best handled using
> a symbolic root. In other words, the Windows provider might support a
> root of "${MY_DOCUMENTS}" just as the Unix provider might support a
> root of "${HOME}". Just a thought, and a separate topic, I believe.)
Someday it would be good to have a desktop provider that knows about
virtual folders and other desktop/shell concepts.
-Alan.
More information about the nio-discuss
mailing list