2323/**
2424 * Utility class that provides methods to manipulate filenames and filepaths.
2525 * <p>
26- * This class defines three basic components within a filename (example C:\dev\file.txt):
26+ * This class defines four basic components within a filename (example C:\dev\project \file.txt):
2727 * <ul>
28- * <li>the path - C:\dev
28+ * <li>the prefix - C:\
29+ * <li>the path - dev\project
2930 * <li>the name - file.txt
3031 * <li>the extension - txt
3132 * </ul>
6566 * @author Martin Cooper
6667 * @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a>
6768 * @author Stephen Colebourne
68- * @version $Id: FilenameUtils.java,v 1.25 2004/10/31 04:17:34 bayard Exp $
69+ * @version $Id: FilenameUtils.java,v 1.26 2004/11/22 01:11:55 scolebourne Exp $
6970 * @since Commons IO 1.1
7071 */
7172public class FilenameUtils {
@@ -90,11 +91,119 @@ public class FilenameUtils {
9091 */
9192 private static final char SYSTEM_SEPARATOR = File .separatorChar ;
9293
94+ // /**
95+ // * The separator character that is the opposite of the system separator.
96+ // */
97+ // private static final char OTHER_SEPARATOR;
98+ // static {
99+ // if (SYSTEM_SEPARATOR == WINDOWS_SEPARATOR) {
100+ // OTHER_SEPARATOR = UNIX_SEPARATOR;
101+ // } else {
102+ // OTHER_SEPARATOR = WINDOWS_SEPARATOR;
103+ // }
104+ // }
105+
93106 /**
94107 * Instances should NOT be constructed in standard programming.
95108 */
96109 public FilenameUtils () { }
97110
111+ // //-----------------------------------------------------------------------
112+ // /**
113+ // * Checks if the character is a separator.
114+ // *
115+ // * @param ch the character to check
116+ // * @return true if it is a separators
117+ // */
118+ // private static boolean isSeparator(char ch) {
119+ // return (ch == UNIX_SEPARATOR) || (ch == WINDOWS_SEPARATOR);
120+ // }
121+ //
122+ // //-----------------------------------------------------------------------
123+ // /**
124+ // * Normalizes a path, removing double and single dot path steps.
125+ // * <p>
126+ // * This method normalizes a path to a standard format.
127+ // * The input may contain separators in either Unix or Windows format.
128+ // * The output will contain separators in the format of the system.
129+ // * <p>
130+ // * A double slash will be merged to a single slash (thus UNC names are not handled).
131+ // * A single dot path segment will be removed with no other effect.
132+ // * A double dot will cause that path segment and the one before to be removed.
133+ // * If the double dot has no parent path segment to work with, <code>null</code>
134+ // * is returned.
135+ // * <pre>
136+ // * /foo// --> /foo/
137+ // * /foo/./ --> /foo/
138+ // * /foo/../bar --> /bar
139+ // * /foo/../bar/ --> /bar/
140+ // * /foo/../bar/../baz --> /baz
141+ // * //foo//./bar --> /foo/bar
142+ // * /../ --> null
143+ // * ../foo --> null
144+ // * foo/../../bar --> null
145+ // * foo/../bar --> bar
146+ // * </pre>
147+ // *
148+ // * @param path the path to normalize, null returns null
149+ // * @return the normalized String, or null if too many ..'s.
150+ // * @todo prefixes for Windows
151+ // */
152+ // public static String normalize(String path) {
153+ // if (path == null) {
154+ // return null;
155+ // }
156+ // char[] array = path.toCharArray();
157+ // int size = array.length;
158+ // // fix separators
159+ // for (int i = 0; i < array.length; i++) {
160+ // if (array[i] == OTHER_SEPARATOR) {
161+ // array[i] = SYSTEM_SEPARATOR;
162+ // }
163+ // }
164+ // // adjoining slashes
165+ // for (int i = 1; i < size; i++) {
166+ // if (array[i] == SYSTEM_SEPARATOR && array[i - 1] == SYSTEM_SEPARATOR) {
167+ // System.arraycopy(array, i, array, i - 1, size - i);
168+ // size--;
169+ // i--;
170+ // }
171+ // }
172+ // // dot slash
173+ // for (int i = 2; i < size; i++) {
174+ // if (array[i] == SYSTEM_SEPARATOR && array[i - 1] == '.' &&
175+ // array[i - 2] == SYSTEM_SEPARATOR) {
176+ // System.arraycopy(array, i, array, i - 2, size - i);
177+ // size -=2;
178+ // i--;
179+ // }
180+ // }
181+ // // double dot slash
182+ // outer:
183+ // for (int i = 2; i < size; i++) {
184+ // if (array[i] == SYSTEM_SEPARATOR && array[i - 1] == '.' &&
185+ // array[i - 2] == '.' && (i == 2 || array[i - 3] == SYSTEM_SEPARATOR)) {
186+ // if (i == 2) {
187+ // return null;
188+ // }
189+ // int j;
190+ // for (j = i - 4 ; j >= 0; j--) {
191+ // if (array[j] == SYSTEM_SEPARATOR) {
192+ // System.arraycopy(array, i, array, j, size - i);
193+ // size -= (i - j);
194+ // i = j + 1;
195+ // continue outer;
196+ // }
197+ // }
198+ // System.arraycopy(array, i + 1, array, 0, size - i - 1);
199+ // size -= (i + 1);
200+ // i = 1;
201+ // }
202+ // }
203+ //
204+ // return new String(array, 0, size);
205+ // }
206+
98207 //-----------------------------------------------------------------------
99208 /**
100209 * Normalize a path.
@@ -322,6 +431,62 @@ public static String separatorsToSystem(String path) {
322431 }
323432
324433 //-----------------------------------------------------------------------
434+ // /**
435+ // * Returns the length of the filename prefix, such as <code>C:/</code> or <code>~/</code>.
436+ // * <p>
437+ // * This method will handle a file in either Unix or Windows format.
438+ // * The prefix includes the first slash in the full filename.
439+ // * <pre>
440+ // * Windows:
441+ // * a\b\c.txt --> "" --> relative
442+ // * \a\b\c.txt --> "\" --> drive relative
443+ // * C:\a\b\c.txt --> "C:\" --> absolute
444+ // * \\server\a\b\c.txt --> "\\server\" --> UNC
445+ // *
446+ // * Unix:
447+ // * a/b/c.txt --> "" --> relative
448+ // * /a/b/c.txt --> "/" --> absolute
449+ // * ~/a/b/c.txt --> "~/" --> current user relative
450+ // * ~user/a/b/c.txt --> "~user/" --> named user relative
451+ // * </pre>
452+ // *
453+ // * @param filename the filename to find the prefix in, null returns -1
454+ // * @return the length of the prefix, -1 if invalid or null
455+ // */
456+ // public static int getPrefixLength(String filename) {
457+ // if (filename == null) {
458+ // return -1;
459+ // }
460+ // int len = filename.length();
461+ // if (len == 0) {
462+ // return 0;
463+ // }
464+ // if (SYSTEM_SEPARATOR == WINDOWS_SEPARATOR) {
465+ // char ch0 = filename.charAt(0);
466+ // if (len == 1) {
467+ // return (isSeparator(ch0) ? 1 : 0);
468+ // } else {
469+ // char ch1 = filename.charAt(1);
470+ // if (ch1 == ':') {
471+ // ch0 = Character.toUpperCase(ch0);
472+ // if (ch0 < 'A' || ch0 > 'Z' || len == 2 || isSeparator(filename.charAt(2)) == false) {
473+ // return -1;
474+ // }
475+ // return 3;
476+ // } else if (isSeparator(ch0) && isSeparator(ch1)) {
477+ // int pos = Math.min(
478+ // filename.indexOf(UNIX_SEPARATOR, 2),
479+ // filename.indexOf(WINDOWS_SEPARATOR, 2));
480+ // return (pos == -1 || pos == 2 ? -1 : pos + 1);
481+ // } else {
482+ // return (isSeparator(ch0) ? 1 : 0);
483+ // }
484+ // }
485+ // } else {
486+ // }
487+ // return 0;
488+ // }
489+
325490 /**
326491 * Returns the index of the last directory separator character.
327492 * <p>
@@ -330,7 +495,7 @@ public static String separatorsToSystem(String path) {
330495 *
331496 * @param filename the filename to find the last path separator in, null returns -1
332497 * @return the index of the last separator character, or -1 if there
333- * is no such character.
498+ * is no such character
334499 */
335500 public static int indexOfLastSeparator (String filename ) {
336501 if (filename == null ) {
@@ -350,7 +515,7 @@ public static int indexOfLastSeparator(String filename) {
350515 *
351516 * @param filename the filename to find the last path separator in, null returns -1
352517 * @return the index of the last separator character, or -1 if there
353- * is no such character.
518+ * is no such character
354519 */
355520 public static int indexOfExtension (String filename ) {
356521 if (filename == null ) {
@@ -362,6 +527,39 @@ public static int indexOfExtension(String filename) {
362527 }
363528
364529 //-----------------------------------------------------------------------
530+ // /**
531+ // * Gets the prefix from a full filename, such as <code>C:/</code> or <code>~/</code>.
532+ // * <p>
533+ // * This method will handle a file in either Unix or Windows format.
534+ // * The prefix includes the first slash in the full filename.
535+ // * <pre>
536+ // * Windows:
537+ // * a\b\c.txt --> "" --> relative
538+ // * \a\b\c.txt --> "\" --> drive relative
539+ // * C:\a\b\c.txt --> "C:\" --> absolute
540+ // * \\server\a\b\c.txt --> "\\server\" --> UNC
541+ // *
542+ // * Unix:
543+ // * a/b/c.txt --> "" --> relative
544+ // * /a/b/c.txt --> "/" --> absolute
545+ // * ~/a/b/c.txt --> "~/" --> current user relative
546+ // * ~user/a/b/c.txt --> "~user/" --> named user relative
547+ // * </pre>
548+ // *
549+ // * @param filename the filename to query, null returns null
550+ // * @return the prefix of the file, null if invalid
551+ // */
552+ // public static String getPrefix(String filename) {
553+ // if (filename == null) {
554+ // return null;
555+ // }
556+ // int len = getPrefixLength(filename);
557+ // if (len < 0) {
558+ // return null;
559+ // }
560+ // return filename.substring(0, len);
561+ // }
562+
365563 /**
366564 * Gets the path from a full filename.
367565 * <p>
@@ -553,37 +751,41 @@ public static boolean isExtension(String filename, Collection extensions) {
553751 return isExtension (filename , array );
554752 }
555753
754+ //-----------------------------------------------------------------------
556755 /**
557756 * See if a particular piece of text, often a filename,
558757 * matches to a specified wildcard, as seen on DOS/UNIX command lines.
758+ *
759+ * @param filename the filename to match on
760+ * @param wildcard the wildcard string to match against
761+ * @return true if the filename matches the wilcard string
559762 */
560- public static boolean wildcardMatch (String text , String wildcard ) {
763+ public static boolean wildcardMatch (String filename , String wildcard ) {
561764 String [] wcs = splitOnTokens (wildcard );
562765
563766 int textIdx = 0 ;
564767 int wcsIdx = 0 ;
565768 boolean anyChars = false ;
566769
567770 // loop whilst tokens and text left to process
568- while (wcsIdx < wcs .length && textIdx < text .length ()) {
771+ while (wcsIdx < wcs .length && textIdx < filename .length ()) {
569772
570773 // ? so move to next text char
571774 if (wcs [wcsIdx ].equals ("?" )) {
572775 textIdx ++;
573- } else
574- if (!wcs [wcsIdx ].equals ("*" )) {
776+ } else if (!wcs [wcsIdx ].equals ("*" )) {
575777 // matching text token
576778 if (anyChars ) {
577779 // any chars then try to locate text token
578- textIdx = text .indexOf (wcs [wcsIdx ], textIdx );
780+ textIdx = filename .indexOf (wcs [wcsIdx ], textIdx );
579781
580782 if (textIdx == -1 ) {
581783 // token not found
582784 return false ;
583785 }
584786 } else {
585787 // matching from current position
586- if (!text .startsWith (wcs [wcsIdx ], textIdx )) {
788+ if (!filename .startsWith (wcs [wcsIdx ], textIdx )) {
587789 // couldnt match token
588790 return false ;
589791 }
@@ -608,12 +810,12 @@ public static boolean wildcardMatch(String text, String wildcard) {
608810 }
609811
610812 // ran out of text chars
611- if (textIdx > text .length ()) {
813+ if (textIdx > filename .length ()) {
612814 return false ;
613815 }
614816
615817 // didnt match all text chars, only ok if any chars set
616- if (textIdx < text .length () && !anyChars ) {
818+ if (textIdx < filename .length () && !anyChars ) {
617819 return false ;
618820 }
619821
@@ -624,13 +826,13 @@ public static boolean wildcardMatch(String text, String wildcard) {
624826 // package level so a unit test may run on this
625827 static String [] splitOnTokens (String text ) {
626828 char [] array = text .toCharArray ();
627- if (text .indexOf ("?" ) == -1 && text .indexOf ("*" ) == -1 ) {
829+ if (text .indexOf ("?" ) == -1 && text .indexOf ("*" ) == -1 ) {
628830 return new String [] { text };
629831 }
630832
631833 ArrayList list = new ArrayList ();
632834 StringBuffer buffer = new StringBuffer ();
633- for (int i = 0 ; i < array .length ; i ++) {
835+ for (int i = 0 ; i < array .length ; i ++) {
634836 if (array [i ] == '?' || array [i ] == '*' ) {
635837 if (buffer .length () != 0 ) {
636838 list .add (buffer .toString ());
@@ -641,12 +843,11 @@ static String[] splitOnTokens(String text) {
641843 buffer .append (array [i ]);
642844 }
643845 }
644- if (buffer .length () != 0 ) {
846+ if (buffer .length () != 0 ) {
645847 list .add (buffer .toString ());
646848 }
647849
648850 return (String []) list .toArray (new String [0 ]);
649851 }
650-
651852
652853}
0 commit comments