• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.unicode.cldr.util;
2 
3 import java.io.File;
4 import java.nio.file.Path;
5 import java.nio.file.Paths;
6 
7 /**
8  * Recommended utility methods for normalizing paths used throughout the CLDR
9  * libraries.
10  *
11  * <p>The methods in this class are used to normalize file and directory paths
12  * such that resulting paths are:
13  * <ul>
14  *     <li>Absolute with respect to the current working directory (if relative).
15  *     <li>Normalized with respect to "upward" parent path segments.
16  * </ul>
17  *
18  * <p>For example if the current directory is {@code "/home/user/work/cldr"}:
19  * <pre>{@code
20  * // Append to current directory.
21  * getNormalizedPathString("foo/bar") == "/home/user/work/cldr/foo/bar"
22  * // Resolve parent path segments.
23  * getNormalizedPathString("../bar") == "/home/user/work/bar"
24  * // Retain (but normalize) absolute paths.
25  * getNormalizedPathString("/tmp/foo/../bar") == "/tmp/bar"
26  * }</pre>
27  *
28  * <p>Note that it is very important to realize that this is NOT the same as
29  * obtaining the "canonical" path (e.g. via {@link File#getCanonicalPath()}
30  * since the methods in this class <em>do not follow symbolic links</em>.
31  *
32  * <p>This is important because in some build systems (e.g. Bazel), file
33  * hierarchies are created by mapping files using symbolic links, and there's
34  * no necessary reason that the canonical file path preserves the same relative
35  * relationship between files.
36  *
37  * <p>For example Bazel uses a content addressed file cache, so every file used
38  * at build time has a canonical path of something like:
39  * <pre>{@code
40  *     /tmp/build/cache/<hex-formatted-content-fingerprint>
41  * }</pre>
42  *
43  * <p>These files are them mapped (via symbolic links) to a hierarchy such as:
44  * <pre>{@code
45  *     /<buid-root>/common/supplemental/plurals.xml
46  *     /<buid-root>/common/supplemental/pluralRanges.xml
47  *     ...
48  *     /<buid-root>/common/dtd/ldmlSupplemental.dtd
49  * }</pre>
50  *
51  * <p>When the XML files are parsed by the CLDR library, the DTD file is found
52  * via the relative path {@code "../../common/dtd/ldmlSupplemental.dtd}.
53  *
54  * <p>If the canonical path for these XML files were given to the XML parser, it
55  * would attempt to resolve the DTD file location as:
56  * <pre>{@code
57  * /tmp/build/cache/<hex-formatted-content-fingerprint>/../../common/dtd/ldmlSupplemental.dtd
58  * }</pre>
59  * which is just:
60  * <pre>{@code
61  * /tmp/build/common/dtd/ldmlSupplemental.dtd
62  * }</pre>
63  * which will obviously not work.
64  *
65  * <p>Over time the CLDR libraries should transition to using {@link Path}
66  * instances (in favour of {@link File} or strings) when handling file paths and
67  * hopefully some of these methods can eventually be deprecated and removed.
68  */
69 public final class PathUtilities {
70     /** Returns the normalized, absolute path string for the given path. */
getNormalizedPathString(String first, String... rest)71     public static String getNormalizedPathString(String first, String... rest) {
72         return getNormalizedPath(first, rest).toString();
73     }
74 
75     /** Returns the normalized, absolute path string of the given file. */
getNormalizedPathString(File file)76     public static String getNormalizedPathString(File file) {
77         return getNormalizedPath(file).toString();
78     }
79 
80     /** Returns the normalized, absolute path string of the given path. */
getNormalizedPathString(Path path)81     public static String getNormalizedPathString(Path path) {
82         return getNormalizedPath(path).toString();
83     }
84 
85     /** Returns the normalized, absolute path of the given path segments. */
getNormalizedPath(String first, String... rest)86     public static Path getNormalizedPath(String first, String... rest) {
87         return getNormalizedPath(Paths.get(first, rest));
88     }
89 
90     /** Returns the normalized, absolute path of the given file. */
getNormalizedPath(File file)91     public static Path getNormalizedPath(File file) {
92         return getNormalizedPath(Paths.get(file.getPath()));
93     }
94 
95     /** Returns the normalized, absolute path of the given path. */
getNormalizedPath(Path path)96     public static Path getNormalizedPath(Path path) {
97         return path.toAbsolutePath().normalize();
98     }
99 
PathUtilities()100     private PathUtilities() {}
101 }
102