scolebourne 2004/11/22 16:04:29
Modified: io/src/test/org/apache/commons/io FilenameUtilsTestCase.java
io/src/java/org/apache/commons/io FilenameUtils.java
Log:
Add methods to handle filename prefixes
Revision Changes Path
1.20 +166 -6
jakarta-commons/io/src/test/org/apache/commons/io/FilenameUtilsTestCase.java
Index: FilenameUtilsTestCase.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/io/src/test/org/apache/commons/io/FilenameUtilsTestCase.java,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- FilenameUtilsTestCase.java 31 Oct 2004 00:03:03 -0000 1.19
+++ FilenameUtilsTestCase.java 23 Nov 2004 00:04:29 -0000 1.20
@@ -113,6 +113,7 @@
public void testNormalize() throws Exception {
String[] src =
{
+ null,
"",
"/",
"///",
@@ -129,10 +130,14 @@
"/foo/.././bar/",
"//foo//./bar",
"/../",
- "/foo/../../" };
+ "/foo/../../",
+ "../foo",
+ "foo/../../bar",
+ "foo/../bar" };
String[] dest =
{
+ null,
"",
"/",
"/",
@@ -149,15 +154,19 @@
"/bar/",
"/foo/bar",
null,
- null };
+ null,
+ null,
+ null,
+ "bar" };
assertEquals("Oops, test writer goofed", src.length, dest.length);
for (int i = 0; i < src.length; i++) {
+ String destStr = FilenameUtils.separatorsToSystem(dest[i]);
+ String resultStr = FilenameUtils.normalize(src[i]);
assertEquals(
- "Check if '" + src[i] + "' normalized to '" + dest[i] + "'",
- dest[i],
- FilenameUtils.normalize(src[i]));
+ "Check if '" + src[i] + "' normalized to '" + destStr + "',
was '" + resultStr + "'",
+ destStr, resultStr);
}
}
@@ -214,6 +223,46 @@
}
//-----------------------------------------------------------------------
+ public void testGetPrefixLength() {
+ assertEquals(-1, FilenameUtils.getPrefixLength(null));
+ if (WINDOWS) {
+ assertEquals(-1,
FilenameUtils.getPrefixLength("1:\\a\\b\\c.txt"));
+ assertEquals(-1, FilenameUtils.getPrefixLength("1:"));
+ assertEquals(-1, FilenameUtils.getPrefixLength("1:a"));
+ assertEquals(-1,
FilenameUtils.getPrefixLength("\\\\\\a\\b\\c.txt"));
+ assertEquals(-1, FilenameUtils.getPrefixLength("\\\\a"));
+
+ assertEquals(0, FilenameUtils.getPrefixLength("a\\b\\c.txt"));
+ assertEquals(1, FilenameUtils.getPrefixLength("\\a\\b\\c.txt"));
+ assertEquals(3,
FilenameUtils.getPrefixLength("C:\\a\\b\\c.txt"));
+ assertEquals(9,
FilenameUtils.getPrefixLength("\\\\server\\a\\b\\c.txt"));
+
+ assertEquals(0, FilenameUtils.getPrefixLength("a/b/c.txt"));
+ assertEquals(1, FilenameUtils.getPrefixLength("/a/b/c.txt"));
+ assertEquals(3, FilenameUtils.getPrefixLength("C:/a/b/c.txt"));
+ assertEquals(9,
FilenameUtils.getPrefixLength("//server/a/b/c.txt"));
+
+ assertEquals(0, FilenameUtils.getPrefixLength("~/a/b/c.txt"));
+ assertEquals(0,
FilenameUtils.getPrefixLength("~user/a/b/c.txt"));
+ } else {
+ assertEquals(-1, FilenameUtils.getPrefixLength("~"));
+ assertEquals(-1, FilenameUtils.getPrefixLength("~user"));
+
+ assertEquals(0, FilenameUtils.getPrefixLength("a/b/c.txt"));
+ assertEquals(1, FilenameUtils.getPrefixLength("/a/b/c.txt"));
+ assertEquals(2, FilenameUtils.getPrefixLength("~/a/b/c.txt"));
+ assertEquals(6,
FilenameUtils.getPrefixLength("~user/a/b/c.txt"));
+
+ assertEquals(0, FilenameUtils.getPrefixLength("a\\b\\c.txt"));
+ assertEquals(1, FilenameUtils.getPrefixLength("\\a\\b\\c.txt"));
+ assertEquals(2, FilenameUtils.getPrefixLength("~\\a\\b\\c.txt"));
+ assertEquals(6,
FilenameUtils.getPrefixLength("~user\\a\\b\\c.txt"));
+
+ assertEquals(0,
FilenameUtils.getPrefixLength("C:\\a\\b\\c.txt"));
+ assertEquals(1,
FilenameUtils.getPrefixLength("\\\\server\\a\\b\\c.txt"));
+ }
+ }
+
public void testIndexOfLastSeparator() {
assertEquals(-1, FilenameUtils.indexOfLastSeparator(null));
assertEquals(-1,
FilenameUtils.indexOfLastSeparator("noseperator.inthispath"));
@@ -233,6 +282,46 @@
}
//-----------------------------------------------------------------------
+ public void testGetPrefix() {
+ assertEquals(null, FilenameUtils.getPrefix(null));
+ if (WINDOWS) {
+ assertEquals(null, FilenameUtils.getPrefix("1:\\a\\b\\c.txt"));
+ assertEquals(null, FilenameUtils.getPrefix("1:"));
+ assertEquals(null, FilenameUtils.getPrefix("1:a"));
+ assertEquals(null, FilenameUtils.getPrefix("\\\\\\a\\b\\c.txt"));
+ assertEquals(null, FilenameUtils.getPrefix("\\\\a"));
+
+ assertEquals("", FilenameUtils.getPrefix("a\\b\\c.txt"));
+ assertEquals("\\", FilenameUtils.getPrefix("\\a\\b\\c.txt"));
+ assertEquals("C:\\", FilenameUtils.getPrefix("C:\\a\\b\\c.txt"));
+ assertEquals("\\\\server\\",
FilenameUtils.getPrefix("\\\\server\\a\\b\\c.txt"));
+
+ assertEquals("", FilenameUtils.getPrefix("a/b/c.txt"));
+ assertEquals("/", FilenameUtils.getPrefix("/a/b/c.txt"));
+ assertEquals("C:/", FilenameUtils.getPrefix("C:/a/b/c.txt"));
+ assertEquals("//server/",
FilenameUtils.getPrefix("//server/a/b/c.txt"));
+
+ assertEquals("", FilenameUtils.getPrefix("~/a/b/c.txt"));
+ assertEquals("", FilenameUtils.getPrefix("~user/a/b/c.txt"));
+ } else {
+ assertEquals(null, FilenameUtils.getPrefix("~"));
+ assertEquals(null, FilenameUtils.getPrefix("~user"));
+
+ assertEquals("", FilenameUtils.getPrefix("a/b/c.txt"));
+ assertEquals("/", FilenameUtils.getPrefix("/a/b/c.txt"));
+ assertEquals("~/", FilenameUtils.getPrefix("~/a/b/c.txt"));
+ assertEquals("~user/",
FilenameUtils.getPrefix("~user/a/b/c.txt"));
+
+ assertEquals("", FilenameUtils.getPrefix("a\\b\\c.txt"));
+ assertEquals("\\", FilenameUtils.getPrefix("\\a\\b\\c.txt"));
+ assertEquals("~\\", FilenameUtils.getPrefix("~\\a\\b\\c.txt"));
+ assertEquals("~user\\",
FilenameUtils.getPrefix("~user\\a\\b\\c.txt"));
+
+ assertEquals("", FilenameUtils.getPrefix("C:\\a\\b\\c.txt"));
+ assertEquals("\\",
FilenameUtils.getPrefix("\\\\server\\a\\b\\c.txt"));
+ }
+ }
+
public void testGetPath() {
assertEquals(null, FilenameUtils.getPath(null));
assertEquals("", FilenameUtils.getPath("noseperator.inthispath"));
@@ -240,6 +329,67 @@
assertEquals("a/b", FilenameUtils.getPath("a/b/c"));
assertEquals("a/b/c", FilenameUtils.getPath("a/b/c/"));
assertEquals("a\\b", FilenameUtils.getPath("a\\b\\c"));
+ if (WINDOWS) {
+ assertEquals(null, FilenameUtils.getPath("1:/a/b/c.txt"));
+ assertEquals(null, FilenameUtils.getPath("1:"));
+ assertEquals(null, FilenameUtils.getPath("1:a"));
+ assertEquals(null, FilenameUtils.getPath("///a/b/c.txt"));
+ assertEquals(null, FilenameUtils.getPath("//a"));
+
+ assertEquals("a/b", FilenameUtils.getPath("a/b/c.txt"));
+ assertEquals("a/b", FilenameUtils.getPath("/a/b/c.txt"));
+ assertEquals("a/b", FilenameUtils.getPath("C:/a/b/c.txt"));
+ assertEquals("a/b", FilenameUtils.getPath("//server/a/b/c.txt"));
+
+ assertEquals("~/a/b", FilenameUtils.getPath("~/a/b/c.txt"));
+ assertEquals("~user/a/b",
FilenameUtils.getPath("~user/a/b/c.txt"));
+ } else {
+ assertEquals(null, FilenameUtils.getPath("~"));
+ assertEquals(null, FilenameUtils.getPath("~user"));
+
+ assertEquals("a/b", FilenameUtils.getPath("a/b/c.txt"));
+ assertEquals("a/b", FilenameUtils.getPath("/a/b/c.txt"));
+ assertEquals("a/b", FilenameUtils.getPath("~/a/b/c.txt"));
+ assertEquals("a/b", FilenameUtils.getPath("~user/a/b/c.txt"));
+
+ assertEquals("C:/a/b", FilenameUtils.getPath("C:/a/b/c.txt"));
+ assertEquals("/server/a/b",
FilenameUtils.getPath("//server/a/b/c.txt"));
+ }
+ }
+
+ public void testGetFullPath() {
+ assertEquals(null, FilenameUtils.getFullPath(null));
+ assertEquals("",
FilenameUtils.getFullPath("noseperator.inthispath"));
+ assertEquals("a/b", FilenameUtils.getFullPath("a/b/c.txt"));
+ assertEquals("a/b", FilenameUtils.getFullPath("a/b/c"));
+ assertEquals("a/b/c", FilenameUtils.getFullPath("a/b/c/"));
+ assertEquals("a\\b", FilenameUtils.getFullPath("a\\b\\c"));
+ if (WINDOWS) {
+ assertEquals(null, FilenameUtils.getFullPath("1:/a/b/c.txt"));
+ assertEquals(null, FilenameUtils.getFullPath("1:"));
+ assertEquals(null, FilenameUtils.getFullPath("1:a"));
+ assertEquals(null, FilenameUtils.getFullPath("///a/b/c.txt"));
+ assertEquals(null, FilenameUtils.getFullPath("//a"));
+
+ assertEquals("a/b", FilenameUtils.getFullPath("a/b/c.txt"));
+ assertEquals("/a/b", FilenameUtils.getFullPath("/a/b/c.txt"));
+ assertEquals("C:/a/b",
FilenameUtils.getFullPath("C:/a/b/c.txt"));
+ assertEquals("//server/a/b",
FilenameUtils.getFullPath("//server/a/b/c.txt"));
+
+ assertEquals("~/a/b", FilenameUtils.getFullPath("~/a/b/c.txt"));
+ assertEquals("~user/a/b",
FilenameUtils.getFullPath("~user/a/b/c.txt"));
+ } else {
+ assertEquals(null, FilenameUtils.getFullPath("~"));
+ assertEquals(null, FilenameUtils.getFullPath("~user"));
+
+ assertEquals("a/b", FilenameUtils.getFullPath("a/b/c.txt"));
+ assertEquals("/a/b", FilenameUtils.getFullPath("/a/b/c.txt"));
+ assertEquals("~/a/b", FilenameUtils.getFullPath("~/a/b/c.txt"));
+ assertEquals("~user/a/b",
FilenameUtils.getFullPath("~user/a/b/c.txt"));
+
+ assertEquals("C:/a/b",
FilenameUtils.getFullPath("C:/a/b/c.txt"));
+ assertEquals("//server/a/b",
FilenameUtils.getFullPath("//server/a/b/c.txt"));
+ }
}
public void testGetName() {
@@ -249,6 +399,16 @@
assertEquals("c", FilenameUtils.getName("a/b/c"));
assertEquals("", FilenameUtils.getName("a/b/c/"));
assertEquals("c", FilenameUtils.getName("a\\b\\c"));
+ }
+
+ public void testGetBaseName() {
+ assertEquals(null, FilenameUtils.getBaseName(null));
+ assertEquals("noseperator",
FilenameUtils.getBaseName("noseperator.inthispath"));
+ assertEquals("c", FilenameUtils.getBaseName("a/b/c.txt"));
+ assertEquals("c", FilenameUtils.getBaseName("a/b/c"));
+ assertEquals("", FilenameUtils.getBaseName("a/b/c/"));
+ assertEquals("c", FilenameUtils.getBaseName("a\\b\\c"));
+ assertEquals("file.txt", FilenameUtils.getBaseName("file.txt.bak"));
}
public void testGetExtension() {
1.27 +270 -270
jakarta-commons/io/src/java/org/apache/commons/io/FilenameUtils.java
Index: FilenameUtils.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/io/src/java/org/apache/commons/io/FilenameUtils.java,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- FilenameUtils.java 22 Nov 2004 01:11:55 -0000 1.26
+++ FilenameUtils.java 23 Nov 2004 00:04:29 -0000 1.27
@@ -23,37 +23,22 @@
/**
* Utility class that provides methods to manipulate filenames and filepaths.
* <p>
- * This class defines four basic components within a filename (example
C:\dev\project\file.txt):
+ * This class defines six components within a filename (example
C:\dev\project\file.txt):
* <ul>
- * <li>the prefix - C:\
- * <li>the path - dev\project
- * <li>the name - file.txt
- * <li>the extension - txt
+ * <li>the prefix - C:\</li>
+ * <li>the path - dev\project</li>
+ * <li>the full path - C:\dev\project</li>
+ * <li>the name - file.txt</li>
+ * <li>the base name - file</li>
+ * <li>the extension - txt</li>
* </ul>
* The class only supports Unix and Windows style names.
- *
- * <h3>Path-related methods</h3>
- *
- * <p>Methods exist to retrieve the components of a typical file path. For
- * example <code>/www/hosted/mysite/index.html</code>, can be broken into:
- * <ul>
- * <li><code>/www/hosted/mysite/</code> -- retrievable through
- * [EMAIL PROTECTED] #getPath}</li>
- * <li><code>index.html</code> -- retrievable through [EMAIL PROTECTED]
#removePath}</li>
- * <li><code>/www/hosted/mysite/index</code> -- retrievable through
- * [EMAIL PROTECTED] #removeExtension}</li>
- * <li><code>html</code> -- retrievable through [EMAIL PROTECTED]
#getExtension}</li>
- * </ul>
- * There are also methods to [EMAIL PROTECTED] #catPath concatenate two
paths},
- * [EMAIL PROTECTED] #resolveFile resolve a path relative to a File} and
- * [EMAIL PROTECTED] #normalize} a path.
* </p>
- *
* <h3>Origin of code</h3>
* <ul>
- * <li>commons-utils repo</li>
- * <li>Alexandria's FileUtils.</li>
- * <li>Avalon Excalibur's IO.</li>
+ * <li>Commons Utils</li>
+ * <li>Alexandria's FileUtils</li>
+ * <li>Avalon Excalibur's IO</li>
* </ul>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Kevin A. Burton</A>
@@ -91,125 +76,47 @@
*/
private static final char SYSTEM_SEPARATOR = File.separatorChar;
-// /**
-// * The separator character that is the opposite of the system
separator.
-// */
-// private static final char OTHER_SEPARATOR;
-// static {
-// if (SYSTEM_SEPARATOR == WINDOWS_SEPARATOR) {
-// OTHER_SEPARATOR = UNIX_SEPARATOR;
-// } else {
-// OTHER_SEPARATOR = WINDOWS_SEPARATOR;
-// }
-// }
+ /**
+ * The separator character that is the opposite of the system separator.
+ */
+ private static final char OTHER_SEPARATOR;
+ static {
+ if (SYSTEM_SEPARATOR == WINDOWS_SEPARATOR) {
+ OTHER_SEPARATOR = UNIX_SEPARATOR;
+ } else {
+ OTHER_SEPARATOR = WINDOWS_SEPARATOR;
+ }
+ }
/**
* Instances should NOT be constructed in standard programming.
*/
public FilenameUtils() { }
-//
//-----------------------------------------------------------------------
-// /**
-// * Checks if the character is a separator.
-// *
-// * @param ch the character to check
-// * @return true if it is a separators
-// */
-// private static boolean isSeparator(char ch) {
-// return (ch == UNIX_SEPARATOR) || (ch == WINDOWS_SEPARATOR);
-// }
-//
-//
//-----------------------------------------------------------------------
-// /**
-// * Normalizes a path, removing double and single dot path steps.
-// * <p>
-// * This method normalizes a path to a standard format.
-// * The input may contain separators in either Unix or Windows format.
-// * The output will contain separators in the format of the system.
-// * <p>
-// * A double slash will be merged to a single slash (thus UNC names are
not handled).
-// * A single dot path segment will be removed with no other effect.
-// * A double dot will cause that path segment and the one before to be
removed.
-// * If the double dot has no parent path segment to work with,
<code>null</code>
-// * is returned.
-// * <pre>
-// * /foo// --> /foo/
-// * /foo/./ --> /foo/
-// * /foo/../bar --> /bar
-// * /foo/../bar/ --> /bar/
-// * /foo/../bar/../baz --> /baz
-// * //foo//./bar --> /foo/bar
-// * /../ --> null
-// * ../foo --> null
-// * foo/../../bar --> null
-// * foo/../bar --> bar
-// * </pre>
-// *
-// * @param path the path to normalize, null returns null
-// * @return the normalized String, or null if too many ..'s.
-// * @todo prefixes for Windows
-// */
-// public static String normalize(String path) {
-// if (path == null) {
-// return null;
-// }
-// char[] array = path.toCharArray();
-// int size = array.length;
-// // fix separators
-// for (int i = 0; i < array.length; i++) {
-// if (array[i] == OTHER_SEPARATOR) {
-// array[i] = SYSTEM_SEPARATOR;
-// }
-// }
-// // adjoining slashes
-// for (int i = 1; i < size; i++) {
-// if (array[i] == SYSTEM_SEPARATOR && array[i - 1] ==
SYSTEM_SEPARATOR) {
-// System.arraycopy(array, i, array, i - 1, size - i);
-// size--;
-// i--;
-// }
-// }
-// // dot slash
-// for (int i = 2; i < size; i++) {
-// if (array[i] == SYSTEM_SEPARATOR && array[i - 1] == '.' &&
-// array[i - 2] == SYSTEM_SEPARATOR) {
-// System.arraycopy(array, i, array, i - 2, size - i);
-// size -=2;
-// i--;
-// }
-// }
-// // double dot slash
-// outer:
-// for (int i = 2; i < size; i++) {
-// if (array[i] == SYSTEM_SEPARATOR && array[i - 1] == '.' &&
-// array[i - 2] == '.' && (i == 2 || array[i - 3] ==
SYSTEM_SEPARATOR)) {
-// if (i == 2) {
-// return null;
-// }
-// int j;
-// for (j = i - 4 ; j >= 0; j--) {
-// if (array[j] == SYSTEM_SEPARATOR) {
-// System.arraycopy(array, i, array, j, size - i);
-// size -= (i - j);
-// i = j + 1;
-// continue outer;
-// }
-// }
-// System.arraycopy(array, i + 1, array, 0, size - i - 1);
-// size -= (i + 1);
-// i = 1;
-// }
-// }
-//
-// return new String(array, 0, size);
-// }
+ //-----------------------------------------------------------------------
+ /**
+ * Checks if the character is a separator.
+ *
+ * @param ch the character to check
+ * @return true if it is a separators
+ */
+ private static boolean isSeparator(char ch) {
+ return (ch == UNIX_SEPARATOR) || (ch == WINDOWS_SEPARATOR);
+ }
//-----------------------------------------------------------------------
/**
- * Normalize a path.
- * Eliminates "/../" and "/./" in a string. Returns <code>null</code> if
- * the ..'s went past the root.
- * Eg:
+ * Normalizes a path, removing double and single dot path steps.
+ * <p>
+ * This method normalizes a path to a standard format.
+ * The input may contain separators in either Unix or Windows format.
+ * The output will contain separators in the format of the system.
+ * <p>
+ * A double slash will be merged to a single slash (thus UNC names are
not handled).
+ * A single dot path segment will be removed with no other effect.
+ * A double dot will cause that path segment and the one before to be
removed.
+ * If the double dot has no parent path segment to work with,
<code>null</code>
+ * is returned.
* <pre>
* /foo// --> /foo/
* /foo/./ --> /foo/
@@ -218,53 +125,74 @@
* /foo/../bar/../baz --> /baz
* //foo//./bar --> /foo/bar
* /../ --> null
+ * ../foo --> null
+ * foo/../../bar --> null
+ * foo/../bar --> bar
* </pre>
*
- * @param path the path to normalize
- * @return the normalized String, or <code>null</code> if too many ..'s.
- * @todo Make this non-unix specific
- */
- public static String normalize(String path) {
- String normalized = path;
- // Resolve occurrences of "//" in the normalized path
- while (true) {
- int index = normalized.indexOf("//");
- if (index < 0) {
- break;
+ * @param filename the filename to normalize, null returns null
+ * @return the normalized String, or null if too many ..'s.
+ */
+ public static String normalize(String filename) {
+ if (filename == null) {
+ return null;
+ }
+ char[] array = filename.toCharArray();
+ int prefix = getPrefixLength(filename);
+ if (prefix < 0) {
+ return null;
+ }
+
+ // TODO: Use prefix
+
+ int size = array.length;
+ // fix separators
+ for (int i = 0; i < array.length; i++) {
+ if (array[i] == OTHER_SEPARATOR) {
+ array[i] = SYSTEM_SEPARATOR;
}
- normalized =
- normalized.substring(0, index)
- + normalized.substring(index + 1);
}
-
- // Resolve occurrences of "/./" in the normalized path
- while (true) {
- int index = normalized.indexOf("/./");
- if (index < 0) {
- break;
+ // adjoining slashes
+ for (int i = 1; i < size; i++) {
+ if (array[i] == SYSTEM_SEPARATOR && array[i - 1] ==
SYSTEM_SEPARATOR) {
+ System.arraycopy(array, i, array, i - 1, size - i);
+ size--;
+ i--;
}
- normalized =
- normalized.substring(0, index)
- + normalized.substring(index + 2);
}
-
- // Resolve occurrences of "/../" in the normalized path
- while (true) {
- int index = normalized.indexOf("/../");
- if (index < 0) {
- break;
+ // dot slash
+ for (int i = 2; i < size; i++) {
+ if (array[i] == SYSTEM_SEPARATOR && array[i - 1] == '.' &&
+ array[i - 2] == SYSTEM_SEPARATOR) {
+ System.arraycopy(array, i, array, i - 2, size - i);
+ size -=2;
+ i--;
}
- if (index == 0) {
- return null; // Trying to go outside our context
+ }
+ // double dot slash
+ outer:
+ for (int i = 2; i < size; i++) {
+ if (array[i] == SYSTEM_SEPARATOR && array[i - 1] == '.' &&
+ array[i - 2] == '.' && (i == 2 || array[i - 3] ==
SYSTEM_SEPARATOR)) {
+ if (i == 2) {
+ return null;
+ }
+ int j;
+ for (j = i - 4 ; j >= 0; j--) {
+ if (array[j] == SYSTEM_SEPARATOR) {
+ System.arraycopy(array, i, array, j, size - i);
+ size -= (i - j);
+ i = j + 1;
+ continue outer;
+ }
+ }
+ System.arraycopy(array, i + 1, array, 0, size - i - 1);
+ size -= (i + 1);
+ i = 1;
}
- int index2 = normalized.lastIndexOf('/', index - 1);
- normalized =
- normalized.substring(0, index2)
- + normalized.substring(index + 3);
}
-
- // Return the normalized path that we have completed
- return normalized;
+
+ return new String(array, 0, size);
}
/**
@@ -431,61 +359,81 @@
}
//-----------------------------------------------------------------------
-// /**
-// * Returns the length of the filename prefix, such as <code>C:/</code>
or <code>~/</code>.
-// * <p>
-// * This method will handle a file in either Unix or Windows format.
-// * The prefix includes the first slash in the full filename.
-// * <pre>
-// * Windows:
-// * a\b\c.txt --> "" --> relative
-// * \a\b\c.txt --> "\" --> drive relative
-// * C:\a\b\c.txt --> "C:\" --> absolute
-// * \\server\a\b\c.txt --> "\\server\" --> UNC
-// *
-// * Unix:
-// * a/b/c.txt --> "" --> relative
-// * /a/b/c.txt --> "/" --> absolute
-// * ~/a/b/c.txt --> "~/" --> current user relative
-// * ~user/a/b/c.txt --> "~user/" --> named user relative
-// * </pre>
-// *
-// * @param filename the filename to find the prefix in, null returns -1
-// * @return the length of the prefix, -1 if invalid or null
-// */
-// public static int getPrefixLength(String filename) {
-// if (filename == null) {
-// return -1;
-// }
-// int len = filename.length();
-// if (len == 0) {
-// return 0;
-// }
-// if (SYSTEM_SEPARATOR == WINDOWS_SEPARATOR) {
-// char ch0 = filename.charAt(0);
-// if (len == 1) {
-// return (isSeparator(ch0) ? 1 : 0);
-// } else {
-// char ch1 = filename.charAt(1);
-// if (ch1 == ':') {
-// ch0 = Character.toUpperCase(ch0);
-// if (ch0 < 'A' || ch0 > 'Z' || len == 2 ||
isSeparator(filename.charAt(2)) == false) {
-// return -1;
-// }
-// return 3;
-// } else if (isSeparator(ch0) && isSeparator(ch1)) {
-// int pos = Math.min(
-// filename.indexOf(UNIX_SEPARATOR, 2),
-// filename.indexOf(WINDOWS_SEPARATOR, 2));
-// return (pos == -1 || pos == 2 ? -1 : pos + 1);
-// } else {
-// return (isSeparator(ch0) ? 1 : 0);
-// }
-// }
-// } else {
-// }
-// return 0;
-// }
+ /**
+ * Returns the length of the filename prefix, such as <code>C:/</code>
or <code>~/</code>.
+ * <p>
+ * This method will handle a file in either Unix or Windows format.
+ * The prefix includes the first slash in the full filename.
+ * <pre>
+ * Windows:
+ * a\b\c.txt --> "" --> relative
+ * \a\b\c.txt --> "\" --> drive relative
+ * C:\a\b\c.txt --> "C:\" --> absolute
+ * \\server\a\b\c.txt --> "\\server\" --> UNC
+ *
+ * Unix:
+ * a/b/c.txt --> "" --> relative
+ * /a/b/c.txt --> "/" --> absolute
+ * ~/a/b/c.txt --> "~/" --> current user relative
+ * ~user/a/b/c.txt --> "~user/" --> named user relative
+ * </pre>
+ *
+ * @param filename the filename to find the prefix in, null returns -1
+ * @return the length of the prefix, -1 if invalid or null
+ */
+ public static int getPrefixLength(String filename) {
+ if (filename == null) {
+ return -1;
+ }
+ int len = filename.length();
+ if (len == 0) {
+ return 0;
+ }
+ if (SYSTEM_SEPARATOR == WINDOWS_SEPARATOR) {
+ char ch0 = filename.charAt(0);
+ if (len == 1) {
+ return (isSeparator(ch0) ? 1 : 0);
+ } else {
+ char ch1 = filename.charAt(1);
+ if (ch1 == ':') {
+ ch0 = Character.toUpperCase(ch0);
+ if (ch0 < 'A' || ch0 > 'Z' || len == 2 ||
isSeparator(filename.charAt(2)) == false) {
+ return -1;
+ }
+ return 3;
+ } else if (isSeparator(ch0) && isSeparator(ch1)) {
+ int posUnix = filename.indexOf(UNIX_SEPARATOR, 2);
+ int posWin = filename.indexOf(WINDOWS_SEPARATOR, 2);
+ if ((posUnix == -1 && posWin == -1) || posUnix == 2 ||
posWin == 2) {
+ return -1;
+ }
+ posUnix = (posUnix == -1 ? posWin : posUnix);
+ posWin = (posWin == -1 ? posUnix : posWin);
+ return Math.min(posUnix, posWin) + 1;
+ } else {
+ return (isSeparator(ch0) ? 1 : 0);
+ }
+ }
+ } else {
+ char ch0 = filename.charAt(0);
+ char ch1 = filename.charAt(1);
+ if (ch0 == '~') {
+ if (len == 1) {
+ return -1;
+ }
+ int posUnix = filename.indexOf(UNIX_SEPARATOR, 1);
+ int posWin = filename.indexOf(WINDOWS_SEPARATOR, 1);
+ if (posUnix == -1 && posWin == -1) {
+ return -1;
+ }
+ posUnix = (posUnix == -1 ? posWin : posUnix);
+ posWin = (posWin == -1 ? posUnix : posWin);
+ return Math.min(posUnix, posWin) + 1;
+ } else {
+ return (isSeparator(ch0) ? 1 : 0);
+ }
+ }
+ }
/**
* Returns the index of the last directory separator character.
@@ -527,61 +475,95 @@
}
//-----------------------------------------------------------------------
-// /**
-// * Gets the prefix from a full filename, such as <code>C:/</code> or
<code>~/</code>.
-// * <p>
-// * This method will handle a file in either Unix or Windows format.
-// * The prefix includes the first slash in the full filename.
-// * <pre>
-// * Windows:
-// * a\b\c.txt --> "" --> relative
-// * \a\b\c.txt --> "\" --> drive relative
-// * C:\a\b\c.txt --> "C:\" --> absolute
-// * \\server\a\b\c.txt --> "\\server\" --> UNC
-// *
-// * Unix:
-// * a/b/c.txt --> "" --> relative
-// * /a/b/c.txt --> "/" --> absolute
-// * ~/a/b/c.txt --> "~/" --> current user relative
-// * ~user/a/b/c.txt --> "~user/" --> named user relative
-// * </pre>
-// *
-// * @param filename the filename to query, null returns null
-// * @return the prefix of the file, null if invalid
-// */
-// public static String getPrefix(String filename) {
-// if (filename == null) {
-// return null;
-// }
-// int len = getPrefixLength(filename);
-// if (len < 0) {
-// return null;
-// }
-// return filename.substring(0, len);
-// }
+ /**
+ * Gets the prefix from a full filename, such as <code>C:/</code> or
<code>~/</code>.
+ * <p>
+ * This method will handle a file in either Unix or Windows format.
+ * The prefix includes the first slash in the full filename.
+ * <pre>
+ * Windows:
+ * a\b\c.txt --> "" --> relative
+ * \a\b\c.txt --> "\" --> drive relative
+ * C:\a\b\c.txt --> "C:\" --> absolute
+ * \\server\a\b\c.txt --> "\\server\" --> UNC
+ *
+ * Unix:
+ * a/b/c.txt --> "" --> relative
+ * /a/b/c.txt --> "/" --> absolute
+ * ~/a/b/c.txt --> "~/" --> current user relative
+ * ~user/a/b/c.txt --> "~user/" --> named user relative
+ * </pre>
+ *
+ * @param filename the filename to query, null returns null
+ * @return the prefix of the file, null if invalid
+ */
+ public static String getPrefix(String filename) {
+ if (filename == null) {
+ return null;
+ }
+ int len = getPrefixLength(filename);
+ if (len < 0) {
+ return null;
+ }
+ return filename.substring(0, len);
+ }
/**
- * Gets the path from a full filename.
+ * Gets the path from a full filename, which excludes the prefix.
* <p>
* This method will handle a file in either Unix or Windows format.
* The text before the last forward or backslash is returned.
- * This method is roughly equivalent to the unix command
<code>dirname</code>.
* <pre>
- * a/b/c.txt --> a/b
- * a.txt --> ""
- * a/b/c --> a/b
- * a/b/c/ --> a/b/c
+ * ~/a/b/c.txt --> a/b
+ * a.txt --> ""
+ * a/b/c --> a/b
+ * a/b/c/ --> a/b/c
* </pre>
*
* @param filename the filename to query, null returns null
- * @return the path of the file, or an empty string if none exists
+ * @return the path of the file, an empty string if none exists, null if
invalid
*/
public static String getPath(String filename) {
if (filename == null) {
return null;
}
+ int prefix = getPrefixLength(filename);
+ if (prefix < 0) {
+ return null;
+ }
+ int index = indexOfLastSeparator(filename);
+ if (index < 0) {
+ return "";
+ } else {
+ return filename.substring(prefix, index);
+ }
+ }
+
+ /**
+ * Gets the full path from a full filename, which is the prefix + path.
+ * <p>
+ * This method will handle a file in either Unix or Windows format.
+ * The text before the last forward or backslash is returned.
+ * <pre>
+ * ~/a/b/c.txt --> ~/a/b
+ * a.txt --> ""
+ * a/b/c --> a/b
+ * a/b/c/ --> a/b/c
+ * </pre>
+ *
+ * @param filename the filename to query, null returns null
+ * @return the path of the file, an empty string if none exists, null if
invalid
+ */
+ public static String getFullPath(String filename) {
+ if (filename == null) {
+ return null;
+ }
+ int prefix = getPrefixLength(filename); // validate the prefix
+ if (prefix < 0) {
+ return null;
+ }
int index = indexOfLastSeparator(filename);
- if (index == -1) {
+ if (index < 0) {
return "";
} else {
return filename.substring(0, index);
@@ -593,7 +575,6 @@
* <p>
* This method will handle a file in either Unix or Windows format.
* The text after the last forward or backslash is returned.
- * This method is roughly equivalent to the unix command
<code>basename</code>.
* <pre>
* a/b/c.txt --> c.txt
* a.txt --> a.txt
@@ -610,6 +591,25 @@
}
int index = indexOfLastSeparator(filename);
return filename.substring(index + 1);
+ }
+
+ /**
+ * Gets the base name, minus the full path and extension, from a full
filename.
+ * <p>
+ * This method will handle a file in either Unix or Windows format.
+ * The text after the last forward or backslash and before the last dot
is returned.
+ * <pre>
+ * a/b/c.txt --> c
+ * a.txt --> a
+ * a/b/c --> c
+ * a/b/c/ --> ""
+ * </pre>
+ *
+ * @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
+ */
+ public static String getBaseName(String filename) {
+ return removeExtension(getName(filename));
}
/**
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]