Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8208208

SearchPath API for classpath and similar path strings

    XMLWordPrintable

    Details

    • Type: CSR
    • Status: Closed
    • Priority: P4
    • Resolution: Withdrawn
    • Fix Version/s: tbd
    • Component/s: core-libs
    • Labels:
      None
    • Subcomponent:
    • Compatibility Kind:
      source, binary, behavioral
    • Compatibility Risk:
      minimal
    • Compatibility Risk Description:
      java.util.SearchPath is new and has minimal compatibility impact.
    • Interface Kind:
      Java API
    • Scope:
      SE

      Description

      Summary

      API for parsing path strings improves consistency across tools and the various system properties.

      Problem

      The parsing of existing path strings such as java.class.path and java.library.path as well as other paths provided by various tools do not have a consistent implementation. The handling of empty paths and quoting of path separators varies by implementation.
      Quoting of paths is supported only on Windows and is not documented.

      Solution

      Add an immutable java.util.SearchPath class to parse path strings, handling quotes and removing empty elements. SearchPaths can be created using factory methods to parse the path elements from a string, from a List, from a varargs strings, etc. The search path can be used to create a Stream or return the List.

      Specification

      package java.util;
      
      /**
       * SearchPath is an immutable sequence of strings, typically filesystem paths.
       * A search path is created from a {@linkplain #ofPath list of strings} or
       * by {@linkplain #of splitting a string} using the {@link File#pathSeparator}.
       * Empty paths, identified by leading, trailing, or adjacent
       * separator characters are included as empty strings, or
       * can be replaced or removed.
       * <p>
       * Empty path elements, when used in the context of a file system
       * are typically interpreted as {@code "."}, the current working directory,
       * consistent with the use in cases like {@code -Djava.class.path=""} and
       * {@code -cp ""}.
       * <p>
       * Search path elements are available as a {@linkplain #stream stream} or
       * an {@linkplain #toList unmodifiable list}.
       * <p>
       * The {@link File#pathSeparator} character can be included in a path
       * on operating systems that support quoting segments of the string.
       * When splitting a string into the path elements each character
       * between pairs of quotation marks ({@code 'U+0022'}) is considered
       * an ordinary character, including {@code pathSeparator}.
       * The quotation marks are omitted from the path element.
       * An unmatched quotation mark is matched by the end of the string.
       * Note: Though the strings are typically filesystem paths, the
       * search path elements may contain characters that are not valid
       * in file system paths.
       * <p>
       * Example to locate a configuration file:
       * <blockquote><pre>{@code
       * Path p = SearchPath.of("/home/user/.config/:/etc/")
       *      .stream()
       *      .map(Path::of)
       *      .filter(Files::isDirectory)
       *      .filter(q -> Files.exists(q.resolve("xyz.conf")))
       *      .findFirst()
       *      .orElseThrow();
       * }</pre></blockquote>
       *
       * @implNote On Windows, quoting of path segments is supported.
       *
       * <p>
       * Unless otherwise noted, passing a {@code null} argument to a method
       * in this class will cause a {@link NullPointerException} to be thrown.
       * @since XX
       */
      public final class SearchPath {
      
           /**
           * Returns a SearchPath parsed from a string using the {@linkplain File#pathSeparator}.
           * An empty string returns a SearchPath with a list of 1 element, an empty string.
           *
           * @param searchPath a string containing paths separated by {@link File#pathSeparator};
           *                   if {@code null} an empty SearchPath is returned
           * @return a {@code non-null} immutable {@code SearchPath}
           */
          public static SearchPath of(String searchPath) {...}
      
          /**
           * Returns a SearchPath parsed from a string using the {@linkplain File#pathSeparator}
           * replacing empty paths with a string or removing them.
           *
           * @param searchPath a string containing paths separated by {@link File#pathSeparator};
           *                   if {@code null} an empty SearchPath is returned
           * @param emptyPath  a string to replace empty path elements;
           *                   if {@code null}, empty path elements are removed
           * @return a {@code non-null} immutable {@code SearchPath}
           */
          public static SearchPath of(String searchPath, String emptyPath) {...}
      
          /**
           * Returns a SearchPath consisting of the list of strings.
           *
           * @param pathList a {@code non-null} list of path strings
           * @return a {@code non-null} immutable {@code SearchPath}
           * @throws IllegalArgumentException if any of the strings in the list are {@code null}
           */
          public static SearchPath ofPath(List<String> pathList) {...}
      
          /**
           * Returns a SearchPath consisting of the arguments.
           *
           * @param pathElement path string arguments,
           * @return a {@code non-null} immutable {@code SearchPath}
           * @throws NullPointerException if any of the arguments strings are {@code null}
           */
          public static SearchPath ofPath(String... pathElement) {...}
      
          /**
           * Returns {@code true} if the search path is empty, there are no path elements.
           *
           * @return returns {@code true} if the search path is empty, otherwise {@code false}
           */
          public boolean isEmpty() {...}
      
          /**
           * Returns the search path elements as a Stream of strings.
           *
           * @return a {@code Stream<String>} of path elements
           */
          public Stream<String> stream() {...}
      
          /**
           * Returns an unmodifiable {@code List<String>} of the path elements.
           *
           * @return an unmodifiable {@code List<String>} of the path elements
           */
          public List<String> toList() {...}
      
          /**
           * Returns a string with the path elements separated by
           * the {@linkplain File#pathSeparator}.
           * If the search path is empty the string returned is "EMPTY".
           * <p>
           * If quoting is supported and a path element contains the
           * {@link File#pathSeparator} the path element is quoted.
           * @apiNote
           * To be consistent with {@linkplain #of(String) parsing} of an empty
           * string as a search path with a single path element, there is
           * no natural string representation of an empty list.
           * The {@code toString} method does not return null and instead
           * uses this recognizable but unusual string for an empty search path.
           *
           * @return if the search path {@link #isEmpty()} "EMPTY" is returned;
           *          otherwise it is a string with the path elements separated by
           *          the {@link File#pathSeparator}
           *
           */
          public String toString() {...}
      }

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              rriggs Roger Riggs
              Reporter:
              rriggs Roger Riggs
              Reviewed By:
              Chris Hegarty
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: