< 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 >