< prev index next >
src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java
Print this page
@@ -156,11 +156,10 @@
@Override
Iterator<Path> iteratorOf(byte[] path, String childPrefix)
throws IOException {
NodeAndImage ni = checkNode(path);
Node node = ni.node.resolveLink(true);
-
if (!node.isDirectory()) {
throw new NotDirectoryException(getString(path));
}
if (node.isRootDir()) {
@@ -169,11 +168,11 @@
return modulesDirIterator(path, childPrefix);
} else if (node.isPackagesDir()) {
return packagesDirIterator(path, childPrefix);
}
- return nodesToIterator(toJrtPath(path), childPrefix, node.getChildren());
+ return nodesToIterator(toJrtPath(path), ni.symLink, childPrefix, node.getChildren());
}
@Override
byte[] getFileContent(byte[] path) throws IOException {
final NodeAndImage ni = checkResource(path);
@@ -198,47 +197,54 @@
private static class NodeAndImage {
final Node node;
final ImageReader image;
+ // was there a symlink somewhere while resolving this Node from name?
+ final boolean symLink;
- NodeAndImage(Node node, ImageReader image) {
+ NodeAndImage(Node node, ImageReader image, boolean symLink) {
this.node = node;
this.image = image;
+ this.symLink = symLink;
}
byte[] getResource() throws IOException {
return image.getResource(node);
}
}
private NodeAndImage lookup(byte[] path) {
+ return lookup(path, false);
+ }
+
+ private NodeAndImage lookup(byte[] path, boolean symLink) {
ImageReader image = bootImage;
Node node;
try {
node = bootImage.findNode(path);
} catch (RuntimeException re) {
throw new InvalidPathException(getString(path), re.toString());
}
- return node != null ? new NodeAndImage(node, image) : null;
+ return node != null ? new NodeAndImage(node, image, symLink) : null;
}
private NodeAndImage lookupSymbolic(byte[] path) {
for (int i = 1; i < path.length; i++) {
if (path[i] == (byte) '/') {
byte[] prefix = Arrays.copyOfRange(path, 0, i);
- NodeAndImage ni = lookup(prefix);
+ NodeAndImage ni = lookup(prefix, true);
if (ni == null) {
break;
}
if (ni.node.isLink()) {
Node link = ni.node.resolveLink(true);
// resolved symbolic path concatenated to the rest of the path
UTF8String resPath = link.getName().concat(new UTF8String(path, i));
byte[] resPathBytes = resPath.getBytesCopy();
- ni = lookup(resPathBytes);
+ ni = lookup(resPathBytes, true);
return ni != null ? ni : lookupSymbolic(resPathBytes);
}
}
}
@@ -277,15 +283,34 @@
private JrtPath toJrtPath(byte[] path) {
return new JrtPath(this, path);
}
- private Iterator<Path> nodesToIterator(Path path, String childPrefix, List<Node> childNodes) {
- Function<Node, Path> f = childPrefix == null
- ? child -> toJrtPath(child.getNameString())
- : child -> toJrtPath(childPrefix + child.getNameString().substring(1));
- return childNodes.stream().map(f).collect(toList()).iterator();
+ private static final int MODULES_LEN = "/modules/".length();
+ private static final int PACKAGES_LEN = "/packages/".length();
+
+ private Iterator<Path> nodesToIterator(Path path, boolean symLink, String childPrefix, List<Node> childNodes) {
+ // Function that maps name -> Path (adding prefix if needed)
+ Function<String, Path> prefixHandler = childPrefix == null
+ ? childStr -> toJrtPath(childStr)
+ : childStr -> toJrtPath(childPrefix + childStr.substring(1));
+
+ // function to map Node->name
+ Function<Node, String> nodeHandler;
+ if (symLink) {
+ // There was a symlink in the parent dir! We need to make sure that the child paths
+ // use the appropriate parent prefix in the name.
+ String parentStr = path.toAbsolutePath().toString();
+ // "/packages/java.lang/java.base/java/" -> "/packages/java.lang/"
+ String parentPrefix = parentStr.substring(0, 1 + parentStr.indexOf('/', PACKAGES_LEN));
+
+ nodeHandler = node -> parentPrefix + node.getNameString().substring(MODULES_LEN);
+ } else {
+ nodeHandler = Node::getNameString;
+ }
+
+ return childNodes.stream().map(nodeHandler.andThen(prefixHandler)).collect(toList()).iterator();
}
private List<Node> rootChildren;
private synchronized void initRootChildren(byte[] path) {
@@ -295,11 +320,11 @@
}
}
private Iterator<Path> rootDirIterator(byte[] path, String childPrefix) throws IOException {
initRootChildren(path);
- return nodesToIterator(rootPath, childPrefix, rootChildren);
+ return nodesToIterator(rootPath, false, childPrefix, rootChildren);
}
private List<Node> modulesChildren;
private synchronized void initModulesChildren(byte[] path) {
@@ -309,11 +334,11 @@
}
}
private Iterator<Path> modulesDirIterator(byte[] path, String childPrefix) throws IOException {
initModulesChildren(path);
- return nodesToIterator(new JrtPath(this, path), childPrefix, modulesChildren);
+ return nodesToIterator(new JrtPath(this, path), false, childPrefix, modulesChildren);
}
private List<Node> packagesChildren;
private synchronized void initPackagesChildren(byte[] path) {
@@ -323,8 +348,8 @@
}
}
private Iterator<Path> packagesDirIterator(byte[] path, String childPrefix) throws IOException {
initPackagesChildren(path);
- return nodesToIterator(new JrtPath(this, path), childPrefix, packagesChildren);
+ return nodesToIterator(new JrtPath(this, path), false, childPrefix, packagesChildren);
}
}
< prev index next >