You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by sc...@apache.org on 2004/12/04 20:28:40 UTC

cvs commit: jakarta-commons/io/src/java/org/apache/commons/io FilenameUtils.java

scolebourne    2004/12/04 11:28:40

  Modified:    io/src/test/org/apache/commons/io FilenameUtilsTestCase.java
               io/src/java/org/apache/commons/io FilenameUtils.java
  Log:
  Add equals methods, document Unix/Windows behaviour
  
  Revision  Changes    Path
  1.23      +23 -1     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.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- FilenameUtilsTestCase.java	27 Nov 2004 17:00:51 -0000	1.22
  +++ FilenameUtilsTestCase.java	4 Dec 2004 19:28:40 -0000	1.23
  @@ -451,6 +451,28 @@
       }
   
       //-----------------------------------------------------------------------
  +    public void testEquals() {
  +        assertEquals(true, FilenameUtils.equals(null, null));
  +        assertEquals(false, FilenameUtils.equals(null, ""));
  +        assertEquals(false, FilenameUtils.equals("", null));
  +        assertEquals(true, FilenameUtils.equals("", ""));
  +        assertEquals(true, FilenameUtils.equals("file.txt", "file.txt"));
  +        assertEquals(WINDOWS, FilenameUtils.equals("file.txt", "FILE.TXT"));
  +        assertEquals(false, FilenameUtils.equals("a\\b\\file.txt", "a/b/file.txt"));
  +    }
  +
  +    public void testEqualsNormalized() {
  +        assertEquals(true, FilenameUtils.equalsNormalized(null, null));
  +        assertEquals(false, FilenameUtils.equalsNormalized(null, ""));
  +        assertEquals(false, FilenameUtils.equalsNormalized("", null));
  +        assertEquals(true, FilenameUtils.equalsNormalized("", ""));
  +        assertEquals(true, FilenameUtils.equalsNormalized("file.txt", "file.txt"));
  +        assertEquals(WINDOWS, FilenameUtils.equalsNormalized("file.txt", "FILE.TXT"));
  +        assertEquals(true, FilenameUtils.equalsNormalized("a\\b\\file.txt", "a/b/file.txt"));
  +        assertEquals(true, FilenameUtils.equalsNormalized("a\\b\\", "a/b"));
  +    }
  +
  +    //-----------------------------------------------------------------------
       public void testIsExtension() {
           assertEquals(false, FilenameUtils.isExtension(null, (String) null));
           assertEquals(false, FilenameUtils.isExtension("file.txt", (String) null));
  
  
  
  1.31      +134 -26   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.30
  retrieving revision 1.31
  diff -u -r1.30 -r1.31
  --- FilenameUtils.java	27 Nov 2004 17:00:51 -0000	1.30
  +++ FilenameUtils.java	4 Dec 2004 19:28:40 -0000	1.31
  @@ -22,6 +22,16 @@
   /**
    * Utility class that provides methods to manipulate filenames and filepaths.
    * <p>
  + * 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.
  + * <p>
  + * 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.
  + * <p>
    * This class defines six components within a filename (example C:\dev\project\file.txt):
    * <ul>
    * <li>the prefix - C:\</li>
  @@ -31,7 +41,9 @@
    * <li>the base name - file</li>
    * <li>the extension - txt</li>
    * </ul>
  - * 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.
  + * <p>
  + * This class only supports Unix and Windows style names. Prefixes are matched as follows:
    * <pre>
    * 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
    * </pre>
  + * Both prefix styles are matched always, irrespective of the machine that you are
  + * currently running on.
    * 
    * </p>
    * <h3>Origin of code</h3>
  @@ -133,6 +147,9 @@
        * 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.
  +     * <p>
  +     * The output will be the same on both Unix and Windows except
  +     * for the separator character.
        * <pre>
        * /foo//               -->   /foo
        * /foo/./              -->   /foo
  @@ -151,7 +168,7 @@
        * ~/foo/../bar         -->   ~/bar
        * ~/../bar             -->   null
        * </pre>
  -     * (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.
        * <p>
        * 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 <code>pathToAdd</code> is absolute (has a prefix), then it will
        * be normalized and returned.
        * Otherwise, the paths will be joined, normalized and returned.
  +     * <p>
  +     * The output will be the same on both Unix and Windows except
  +     * for the separator character.
        * <pre>
        * /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 (!)
        * </pre>
  -     * 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
        * </pre>
  -     * Both sets of prefixes will be matched regardless of the system
  -     * on which the code runs.
  +     * <p>
  +     * 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 @@
        * <p>
        * This method will handle a file in either Unix or Windows format.
        * The position of the last forward or backslash is returned.
  +     * <p>
  +     * 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.
  +     * <p>
  +     * 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
        * </pre>
  +     * <p>
  +     * 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.
        * <p>
        * 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
        * </pre>
  +     * <p>
  +     * 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.
        * <p>
        * 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
        * </pre>
  +     * <p>
  +     * 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/    --> ""
        * </pre>
  +     * <p>
  +     * 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/    --> ""
        * </pre>
  +     * <p>
  +     * 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        --> ""
        * </pre>
  +     * <p>
  +     * 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.
        * <pre>
        * 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
        * </pre>
  +     * <p>
  +     * 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.
  +     * <p>
  +     * 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.
  +     * <p>
  +     * 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.
        * <p>
        * 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.
        * <p>
        * 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.
        * <p>
        * 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.
  +     * <p>
  +     * 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.
  +     * <pre>
  +     * 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
  +     * </pre>
        * 
        * @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