< prev index next >

src/java.base/share/classes/jdk/internal/loader/URLClassPath.java

Print this page
rev 51675 : 8207690: Parsing API for classpath and similar path strings

@@ -46,18 +46,18 @@
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
 import java.security.cert.Certificate;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.NoSuchElementException;
+import java.util.Objects;
 import java.util.Properties;
 import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.jar.JarFile;
 import java.util.zip.ZipEntry;

@@ -68,10 +68,11 @@
 import java.util.zip.ZipFile;
 
 import jdk.internal.misc.JavaNetURLAccess;
 import jdk.internal.misc.JavaUtilZipFileAccess;
 import jdk.internal.misc.SharedSecrets;
+import jdk.internal.util.PathParser;
 import jdk.internal.util.jar.InvalidJarIndexError;
 import jdk.internal.util.jar.JarIndex;
 import sun.net.util.URLUtil;
 import sun.net.www.ParseUtil;
 import sun.security.action.GetPropertyAction;

@@ -99,11 +100,11 @@
         p = props.getProperty("jdk.net.URLClassPath.disableRestrictedPermissions");
         DISABLE_ACC_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
     }
 
     /* The original search path of URLs. */
-    private final ArrayList<URL> path;
+    private final List<URL> path;
 
     /* The deque of unopened URLs */
     private final ArrayDeque<URL> unopenedUrls;
 
     /* The resulting search path of Loaders */

@@ -162,41 +163,35 @@
         this(urls, null, acc);
     }
 
     /**
      * Constructs a URLClassPath from a class path string.
+     * Empty path strings are later used to open a directory that defaults
+     * to the current directory.
      *
      * @param cp the class path string
      * @param skipEmptyElements indicates if empty elements are ignored or
      *        treated as the current working directory
      *
      * @apiNote Used to create the application class path.
      */
     URLClassPath(String cp, boolean skipEmptyElements) {
-        ArrayList<URL> path = new ArrayList<>();
-        if (cp != null) {
-            // map each element of class path to a file URL
-            int off = 0, next;
-            do {
-                next = cp.indexOf(File.pathSeparator, off);
-                String element = (next == -1)
-                    ? cp.substring(off)
-                    : cp.substring(off, next);
-                if (element.length() > 0 || !skipEmptyElements) {
-                    URL url = toFileURL(element);
-                    if (url != null) path.add(url);
-                }
-                off = next + 1;
-            } while (next != -1);
-        }
+        String[] strings = PathParser
+                .parsePath(Objects.requireNonNullElse(cp, ""),
+                        skipEmptyElements ? null : "");
+        int size = strings.length;
+        ArrayList<URL> path = new ArrayList<>(size);
+        ArrayDeque<URL> unopenedUrls = new ArrayDeque<>(size);
 
         // can't use ArrayDeque#addAll or new ArrayDeque(Collection);
         // it's too early in the bootstrap to trigger use of lambdas
-        int size = path.size();
-        ArrayDeque<URL> unopenedUrls = new ArrayDeque<>(size);
-        for (int i = 0; i < size; i++)
-            unopenedUrls.add(path.get(i));
+        // Add a URL for each path element to the paths and the unopenedUrls.
+        for (String s : strings) {
+            URL url = toFileURL(s);
+            path.add(url);
+            unopenedUrls.add(url);
+        }
 
         this.unopenedUrls = unopenedUrls;
         this.path = path;
         this.jarHandler = null;
         this.acc = null;
< prev index next >