Return-Path:
+ * When dealing with filenames you can hit problems when moving from a Windows
+ * based development machine to a Unix based production machine.
+ * This class aims to help avoid those problems.
+ *
+ * Most methods on this class are designed to work the same on both Unix and Windows.
+ * Both separators (forward and back) are recognised, and both sets of prefixes.
+ * The comparison methods do differ by machine however, comparing case insensitive
+ * on Windows and case sensitive on Unix.
+ * See the javadoc of each method for details.
+ *
* This class defines six components within a filename (example C:\dev\project\file.txt):
*
+ * This class only supports Unix and Windows style names. Prefixes are matched as follows:
*
*
- * The class only supports Unix and Windows style names. Prefixes are matched as follows:
+ * Note that the path of a directory is the parent directory.
+ *
* Windows style:
* a\b\c.txt --> "" --> relative
@@ -45,6 +57,8 @@
* ~/a/b/c.txt --> "~/" --> current user relative
* ~user/a/b/c.txt --> "~user/" --> named user relative
*
+ * Both prefix styles are matched always, irrespective of the machine that you are
+ * currently running on.
*
*
null
* is returned.
+ * + * The output will be the same on both Unix and Windows except + * for the separator character. *
* /foo// --> /foo * /foo/./ --> /foo @@ -151,7 +168,7 @@ * ~/foo/../bar --> ~/bar * ~/../bar --> null *- * (Note the file separator returned will be correct for windows/unix) + * (Note the file separator returned will be correct for Windows/Unix) * * @param filename the filename to normalize, null returns null * @return the normalized String, or null if invalid @@ -232,7 +249,7 @@ } /** - * Concatenates two paths using normal command line style rules. + * Concatenates a filename to a base path using normal command line style rules. *
* The first argument is the base path, the second is the path to concatenate.
* The returned path is always normalized via {@link #normalize(String)},
@@ -241,43 +258,47 @@
* If pathToAdd
is absolute (has a prefix), then it will
* be normalized and returned.
* Otherwise, the paths will be joined, normalized and returned.
+ *
+ * The output will be the same on both Unix and Windows except + * for the separator character. *
* /foo/ + bar --> /foo/bar * /foo/a + bar --> /foo/a/bar - * /foo/c.txt + bar --> /foo/c.txt/bar * /foo/ + ../bar --> /bar * /foo/ + ../../bar --> null * /foo/ + /bar --> /bar * /foo/.. + /bar --> /bar + * /foo + bar/c.txt --> /foo/bar/c.txt + * /foo/c.txt + bar --> /foo/c.txt/bar (!) *- * Note that the first parameter must be a path. If it ends with a name, then + * (!) Note that the first parameter must be a path. If it ends with a name, then * the name will be built into the concatenated path. If this might be a problem, * use {@link #getFullPath(String)} on the base path argument. * * @param basePath the base path to attach to, always treated as a path - * @param pathToAdd path the second path to attach to the first + * @param fullFilenameToAdd the filename (or path) to attach to the base * @return the concatenated path, or null if invalid */ - public static String concat(String basePath, String pathToAdd) { - int prefix = getPrefixLength(pathToAdd); + public static String concat(String basePath, String fullFilenameToAdd) { + int prefix = getPrefixLength(fullFilenameToAdd); if (prefix < 0) { return null; } if (prefix > 0) { - return normalize(pathToAdd); + return normalize(fullFilenameToAdd); } if (basePath == null) { return null; } int len = basePath.length(); if (len == 0) { - return normalize(pathToAdd); + return normalize(fullFilenameToAdd); } char ch = basePath.charAt(len - 1); if (isSeparator(basePath.charAt(len - 1))) { - return normalize(basePath + pathToAdd); + return normalize(basePath + fullFilenameToAdd); } else { - return normalize(basePath + '/' + pathToAdd); + return normalize(basePath + '/' + fullFilenameToAdd); } } @@ -344,8 +365,9 @@ * ~/a/b/c.txt --> "~/" --> current user relative * ~user/a/b/c.txt --> "~user/" --> named user relative * - * Both sets of prefixes will be matched regardless of the system - * on which the code runs. + *
+ * The output will be the same irrespective of the machine that the code is running on. + * ie. both Unix and Windows prefixes are matched regardless. * * @param filename the filename to find the prefix in, null returns -1 * @return the length of the prefix, -1 if invalid or null @@ -406,6 +428,8 @@ *
* This method will handle a file in either Unix or Windows format. * The position of the last forward or backslash is returned. + *
+ * The output will be the same irrespective of the machine that the code is running on. * * @param filename the filename to find the last path separator in, null returns -1 * @return the index of the last separator character, or -1 if there @@ -426,6 +450,8 @@ * This method also checks that there is no directory separator after the last dot. * To do this it uses {@link #indexOfLastSeparator(String)} which will * handle a file in either Unix or Windows format. + *
+ * The output will be the same irrespective of the machine that the code is running on. * * @param filename the filename to find the last path separator in, null returns -1 * @return the index of the last separator character, or -1 if there @@ -459,6 +485,9 @@ * ~/a/b/c.txt --> "~/" --> current user relative * ~user/a/b/c.txt --> "~user/" --> named user relative * + *
+ * The output will be the same irrespective of the machine that the code is running on. + * ie. both Unix and Windows prefixes are matched regardless. * * @param filename the filename to query, null returns null * @return the prefix of the file, null if invalid @@ -476,6 +505,7 @@ /** * Gets the path from a full filename, which excludes the prefix. + * The path of a directory is the parent directory. *
* This method will handle a file in either Unix or Windows format. * The text before the last forward or backslash is returned. @@ -486,6 +516,8 @@ * a/b/c --> a/b * a/b/c/ --> a/b/c * + *
+ * The output will be the same irrespective of the machine that the code is running on. * * @param filename the filename to query, null returns null * @return the path of the file, an empty string if none exists, null if invalid @@ -508,6 +540,7 @@ /** * Gets the full path from a full filename, which is the prefix + path. + * The path of a directory is the parent directory. *
* This method will handle a file in either Unix or Windows format. * The text before the last forward or backslash is returned. @@ -518,6 +551,8 @@ * a/b/c --> a/b * a/b/c/ --> a/b/c * + *
+ * The output will be the same irrespective of the machine that the code is running on. * * @param filename the filename to query, null returns null * @return the path of the file, an empty string if none exists, null if invalid @@ -549,6 +584,8 @@ * a/b/c --> c * a/b/c/ --> "" * + *
+ * The output will be the same irrespective of the machine that the code is running on. * * @param filename the filename to query, null returns null * @return the name of the file without the path, or an empty string if none exists @@ -572,6 +609,8 @@ * a/b/c --> c * a/b/c/ --> "" * + *
+ * The output will be the same irrespective of the machine that the code is running on. * * @param filename the filename to query, null returns null * @return the name of the file without the path, or an empty string if none exists @@ -591,6 +630,8 @@ * a/b.txt/c --> "" * a/b/c --> "" * + *
+ * The output will be the same irrespective of the machine that the code is running on. * * @param filename the filename to retrieve the extension of. * @return the extension of the file or an empty string if none exists. @@ -615,10 +656,12 @@ * There must be no directory separator after the dot. *
* foo.txt --> foo - * a\b\c.jpg --> a\b\c - * a\b\c --> a\b\c - * a.b\c --> a.b\c + * a\b\c.jpg --> a\b\c + * a\b\c --> a\b\c + * a.b\c --> a.b\c *+ *
+ * The output will be the same irrespective of the machine that the code is running on. * * @param filename the filename to query, null returns null * @return the filename minus the extension @@ -637,7 +680,60 @@ //----------------------------------------------------------------------- /** - * Checks whether the extension of the filename is that specified. + * Checks whether two filenames are equal using the case rules of the system. + *
+ * No processing is performed on the filenames other than comparison. + * The check is case sensitive on Unix and case insensitive on Windows. + * + * @param filename1 the first filename to query, may be null + * @param filename2 the second filename to query, may be null + * @return true if the filenames are equal, null equals null + */ + public static boolean equals(String filename1, String filename2) { + if (filename1 == filename2) { + return true; + } + if (filename1 == null || filename2 == null) { + return false; + } + if (SYSTEM_SEPARATOR == WINDOWS_SEPARATOR) { + return filename1.equalsIgnoreCase(filename2); + } else { + return filename1.equals(filename2); + } + } + + /** + * Checks whether two filenames are equal after both have been normalized + * and using the case rules of the system. + *
+ * Both filenames are first passed to {@link #normalize(String)}. + * The check is then performed case sensitive on Unix and case insensitive on Windows. + * + * @param filename1 the first filename to query, may be null + * @param filename2 the second filename to query, may be null + * @return true if the filenames are equal, null equals null + */ + public static boolean equalsNormalized(String filename1, String filename2) { + if (filename1 == filename2) { + return true; + } + if (filename1 == null || filename2 == null) { + return false; + } + filename1 = normalize(filename1); + filename2 = normalize(filename2); + if (SYSTEM_SEPARATOR == WINDOWS_SEPARATOR) { + return filename1.equalsIgnoreCase(filename2); + } else { + return filename1.equals(filename2); + } + } + + //----------------------------------------------------------------------- + /** + * Checks whether the extension of the filename is that specified + * using the case rules of the system. *
* This method obtains the extension as the textual part of the filename * after the last dot. There must be no directory separator after the dot. @@ -663,7 +759,8 @@ } /** - * Checks whether the extension of the filename is one of those specified. + * Checks whether the extension of the filename is one of those specified + * using the case rules of the system. *
* This method obtains the extension as the textual part of the filename * after the last dot. There must be no directory separator after the dot. @@ -698,7 +795,8 @@ } /** - * Checks whether the extension of the filename is one of those specified. + * Checks whether the extension of the filename is one of those specified + * using the case rules of the system. *
* This method obtains the extension as the textual part of the filename * after the last dot. There must be no directory separator after the dot. @@ -721,15 +819,25 @@ //----------------------------------------------------------------------- /** - * See if a particular piece of text, often a filename, - * matches to a specified wildcard, as seen on DOS/UNIX command lines. + * Checks a filename to see if it matches the specified wildcard matcher. + *
+ * The wildcard matcher uses the characters '?' and '*' to represent a + * single or multiple wildcard characters. + * This is the same as often found on Dos/Unix command lines. + *
+ * wildcardMatch("c.txt", "*.txt") --> true + * wildcardMatch("c.txt", "*.jpg") --> false + * wildcardMatch("a/b/c.txt", "a/b/*") --> true + * wildcardMatch("c.txt", "*.???") --> true + * wildcardMatch("c.txt", "*.????") --> false + ** * @param filename the filename to match on - * @param wildcard the wildcard string to match against + * @param wildcardMatcher the wildcard string to match against * @return true if the filename matches the wilcard string */ - public static boolean wildcardMatch(String filename, String wildcard) { - String[] wcs = splitOnTokens(wildcard); + public static boolean wildcardMatch(String filename, String wildcardMatcher) { + String[] wcs = splitOnTokens(wildcardMatcher); int textIdx = 0; int wcsIdx = 0; --------------------------------------------------------------------- To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org For additional commands, e-mail: commons-dev-help@jakarta.apache.org