Skip to content

Commit 9628bca

Browse files
author
Stephen Colebourne
committed
Add indexOfXxx methods to FilenameUtils
git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/io/trunk@140633 13f79535-47bb-0310-9956-ffa450edef68
1 parent 68f11e1 commit 9628bca

2 files changed

Lines changed: 83 additions & 38 deletions

File tree

src/java/org/apache/commons/io/FilenameUtils.java

Lines changed: 63 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,16 @@
1919
import java.io.IOException;
2020

2121
/**
22-
* Common {@link java.io.File} manipulation routines through
23-
* use of a filename/path.
24-
*
22+
* Utility class that provides methods to manipulate filenames and filepaths.
23+
* <p>
24+
* This class defines three basic components within a filename (example C:\dev\file.txt):
25+
* <ul>
26+
* <li>the path - C:\dev
27+
* <li>the name - file.txt
28+
* <li>the extension - txt
29+
* </ul>
30+
* The class only supports Unix and Windows style names.
31+
*
2532
* <h3>Path-related methods</h3>
2633
*
2734
* <p>Methods exist to retrieve the components of a typical file path. For
@@ -56,7 +63,7 @@
5663
* @author Martin Cooper
5764
* @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a>
5865
* @author Stephen Colebourne
59-
* @version $Id: FilenameUtils.java,v 1.19 2004/10/30 22:16:23 scolebourne Exp $
66+
* @version $Id: FilenameUtils.java,v 1.20 2004/10/30 22:41:57 scolebourne Exp $
6067
* @since Commons IO 1.1
6168
*/
6269
public class FilenameUtils {
@@ -66,6 +73,11 @@ public class FilenameUtils {
6673
*/
6774
private static final char INTERNAL_SEPARATOR_CHAR = '/';
6875

76+
/**
77+
* The extension separator character.
78+
*/
79+
private static final char EXTENSION_SEPARATOR = '.';
80+
6981
/**
7082
* The Unix separator character.
7183
*/
@@ -356,14 +368,14 @@ public static String normalize(String path) {
356368
// TODO UNIX/Windows only. Is this a problem?
357369
public static String catPath(String lookupPath, String path) {
358370
// Cut off the last slash and everything beyond
359-
int index = indexOfLastPathSeparator(lookupPath);
371+
int index = indexOfLastSeparator(lookupPath);
360372
String lookup = lookupPath.substring(0, index);
361373
String pth = path;
362374

363375
// Deal with .. by chopping dirs off the lookup path
364376
while (pth.startsWith("../") || pth.startsWith("..\\")) {
365377
if (lookup.length() > 0) {
366-
index = indexOfLastPathSeparator(lookup);
378+
index = indexOfLastSeparator(lookup);
367379
lookup = lookup.substring(0, index);
368380
} else {
369381
// More ..'s than dirs, return null
@@ -377,22 +389,6 @@ public static String catPath(String lookupPath, String path) {
377389
append(File.separator).append(pth).toString();
378390
}
379391

380-
/**
381-
* Return the index of the last 'path separator' character. The 'path
382-
* separator' character is '/' for UNIX systems and '\' for Microsoft
383-
* Windows systems.
384-
*
385-
* @param path The path to find the last path separator in
386-
* @return The index of the last 'path separator' character, or -1 if there
387-
* is no such character.
388-
*/
389-
// KILL: Inline into above method
390-
public static int indexOfLastPathSeparator(String path) {
391-
int lastUnixPos = path.lastIndexOf('/');
392-
int lastWindowsPos = path.lastIndexOf('\\');
393-
return Math.max(lastUnixPos, lastWindowsPos);
394-
}
395-
396392
/**
397393
* Resolve a file <code>filename</code> to it's canonical form. If
398394
* <code>filename</code> is relative (doesn't start with <code>/</code>),
@@ -493,7 +489,7 @@ private static String externalize(String path) {
493489

494490
//-----------------------------------------------------------------------
495491
/**
496-
* Convert all separators to the Unix separator of forward slash.
492+
* Converts all separators to the Unix separator of forward slash.
497493
*
498494
* @param path the path to be changed, null ignored
499495
* @return the updated path
@@ -506,7 +502,7 @@ public static String separatorsToUnix(String path) {
506502
}
507503

508504
/**
509-
* Convert all separators to the Windows separator of backslash.
505+
* Converts all separators to the Windows separator of backslash.
510506
*
511507
* @param path the path to be changed, null ignored
512508
* @return the updated path
@@ -519,7 +515,7 @@ public static String separatorsToWindows(String path) {
519515
}
520516

521517
/**
522-
* Convert all separators to the system separator.
518+
* Converts all separators to the system separator.
523519
*
524520
* @param path the path to be changed, null ignored
525521
* @return the updated path
@@ -528,15 +524,51 @@ public static String separatorsToSystem(String path) {
528524
if (path == null) {
529525
return null;
530526
}
531-
if (SYSTEM_SEPARATOR == UNIX_SEPARATOR) {
532-
return separatorsToUnix(path);
533-
}
534527
if (SYSTEM_SEPARATOR == WINDOWS_SEPARATOR) {
535528
return separatorsToWindows(path);
529+
} else {
530+
return separatorsToUnix(path);
536531
}
537-
path = path.replace(UNIX_SEPARATOR, SYSTEM_SEPARATOR);
538-
path = path.replace(WINDOWS_SEPARATOR, SYSTEM_SEPARATOR);
539-
return path;
532+
}
533+
534+
//-----------------------------------------------------------------------
535+
/**
536+
* Returns the index of the last directory separator character.
537+
* <p>
538+
* This method will handle a file in either Unix or Windows format.
539+
* The position of the last forward or backslash is returned.
540+
*
541+
* @param path the path to find the last path separator in
542+
* @return the index of the last separator character, or -1 if there
543+
* is no such character.
544+
*/
545+
public static int indexOfLastSeparator(String path) {
546+
if (path == null) {
547+
return -1;
548+
}
549+
int lastUnixPos = path.lastIndexOf(UNIX_SEPARATOR);
550+
int lastWindowsPos = path.lastIndexOf(WINDOWS_SEPARATOR);
551+
return Math.max(lastUnixPos, lastWindowsPos);
552+
}
553+
554+
/**
555+
* Returns the index of the last extension separator character, which is a dot.
556+
* <p>
557+
* This method also checks that there is no directory separator after the last dot.
558+
* To do this it uses {@link #indexOfLastSeparator(String)} which will
559+
* handle a file in either Unix or Windows format.
560+
*
561+
* @param path the path to find the last path separator in
562+
* @return the index of the last separator character, or -1 if there
563+
* is no such character.
564+
*/
565+
public static int indexOfExtension(String path) {
566+
if (path == null) {
567+
return -1;
568+
}
569+
int extensionPos = path.lastIndexOf(EXTENSION_SEPARATOR);
570+
int lastSeparator = indexOfLastSeparator(path);
571+
return (lastSeparator > extensionPos ? -1 : extensionPos);
540572
}
541573

542574
}

src/test/org/apache/commons/io/FilenameUtilsTestCase.java

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
* @author Peter Donald
3131
* @author Matthew Hawthorne
3232
* @author Martin Cooper
33-
* @version $Id: FilenameUtilsTestCase.java,v 1.13 2004/10/30 22:16:23 scolebourne Exp $
33+
* @version $Id: FilenameUtilsTestCase.java,v 1.14 2004/10/30 22:41:56 scolebourne Exp $
3434
* @see FilenameUtils
3535
*/
3636
public class FilenameUtilsTestCase extends FileBasedTestCase {
@@ -114,12 +114,6 @@ public void testCatPath() {
114114
assertEquals("C:\\a" + File.separator + "d", FilenameUtils.catPath("C:\\a\\b\\c", "../d"));
115115
}
116116

117-
public void testIndexOfLastPathSeparator() {
118-
assertEquals(-1, FilenameUtils.indexOfLastPathSeparator("noseperator.inthispath"));
119-
assertEquals(3, FilenameUtils.indexOfLastPathSeparator("a/b/c"));
120-
assertEquals(3, FilenameUtils.indexOfLastPathSeparator("a\\b\\c"));
121-
}
122-
123117
// resolveFile
124118

125119
public void testResolveFileDotDot() throws Exception {
@@ -311,4 +305,23 @@ public void testSeparatorsToSystem() {
311305
}
312306
}
313307

308+
//-----------------------------------------------------------------------
309+
public void testIndexOfLastSeparator() {
310+
assertEquals(-1, FilenameUtils.indexOfLastSeparator(null));
311+
assertEquals(-1, FilenameUtils.indexOfLastSeparator("noseperator.inthispath"));
312+
assertEquals(3, FilenameUtils.indexOfLastSeparator("a/b/c"));
313+
assertEquals(3, FilenameUtils.indexOfLastSeparator("a\\b\\c"));
314+
}
315+
316+
public void testIndexOfExtension() {
317+
assertEquals(-1, FilenameUtils.indexOfExtension(null));
318+
assertEquals(-1, FilenameUtils.indexOfExtension("file"));
319+
assertEquals(4, FilenameUtils.indexOfExtension("file.txt"));
320+
assertEquals(13, FilenameUtils.indexOfExtension("a.txt/b.txt/c.txt"));
321+
assertEquals(-1, FilenameUtils.indexOfExtension("a/b/c"));
322+
assertEquals(-1, FilenameUtils.indexOfExtension("a\\b\\c"));
323+
assertEquals(-1, FilenameUtils.indexOfExtension("a/b.notextension/c"));
324+
assertEquals(-1, FilenameUtils.indexOfExtension("a\\b.notextension\\c"));
325+
}
326+
314327
}

0 commit comments

Comments
 (0)