scolebourne    2004/11/27 09:00:51

  Modified:    io/src/test/org/apache/commons/io FilenameUtilsTestCase.java
               io/src/java/org/apache/commons/io FilenameUtils.java
  Log:
  Rewrite catPath, renaming to concat
  
  Revision  Changes    Path
  1.22      +32 -13    
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.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- FilenameUtilsTestCase.java        27 Nov 2004 01:22:05 -0000      1.21
  +++ FilenameUtilsTestCase.java        27 Nov 2004 17:00:51 -0000      1.22
  @@ -82,18 +82,6 @@
       }
   
       //-----------------------------------------------------------------------
  -    public void testCatPath() {
  -        // TODO StringIndexOutOfBoundsException thrown if file doesn't 
contain slash.
  -        // Is this acceptable?
  -        //assertEquals("", FilenameUtils.catPath("a", "b"));
  -
  -        assertEquals("/a" + File.separator + "c", 
FilenameUtils.catPath("/a/b", "c"));
  -        assertEquals("/a" + File.separator + "d", 
FilenameUtils.catPath("/a/b/c", "../d"));
  -        assertEquals("C:\\a" + File.separator + "c", 
FilenameUtils.catPath("C:\\a\\b", "c"));
  -        assertEquals("C:\\a" + File.separator + "d", 
FilenameUtils.catPath("C:\\a\\b\\c", "../d"));
  -    }
  -
  -    //-----------------------------------------------------------------------
       public void testNormalize() throws Exception {
           assertEquals(null, FilenameUtils.normalize(null));
           assertEquals(null, FilenameUtils.normalize(":"));
  @@ -213,6 +201,37 @@
           assertEquals(null, FilenameUtils.normalize("//server/../a"));
           assertEquals(null, FilenameUtils.normalize("//server/.."));
           assertEquals(SEP + SEP + "server" + SEP + "", 
FilenameUtils.normalize("//server/"));
  +    }
  +
  +    //-----------------------------------------------------------------------
  +    public void testConcat() {
  +        assertEquals(null, FilenameUtils.concat("", null));
  +        assertEquals(null, FilenameUtils.concat(null, null));
  +        assertEquals(null, FilenameUtils.concat(null, ""));
  +        assertEquals(null, FilenameUtils.concat(null, "a"));
  +        assertEquals(SEP + "a", FilenameUtils.concat(null, "/a"));
  +        
  +        assertEquals(null, FilenameUtils.concat("", ":")); // invalid prefix
  +        assertEquals(null, FilenameUtils.concat(":", "")); // invalid prefix
  +        
  +        assertEquals("f", FilenameUtils.concat("", "f/"));
  +        assertEquals("f", FilenameUtils.concat("", "f"));
  +        assertEquals("a" + SEP + "f", FilenameUtils.concat("a/", "f/"));
  +        assertEquals("a" + SEP + "f", FilenameUtils.concat("a", "f"));
  +        assertEquals("a" + SEP + "b" + SEP + "f", 
FilenameUtils.concat("a/b/", "f/"));
  +        assertEquals("a" + SEP + "b" + SEP + "f", 
FilenameUtils.concat("a/b", "f"));
  +        
  +        assertEquals("a" + SEP + "f", FilenameUtils.concat("a/b/", "../f/"));
  +        assertEquals("a" + SEP + "f", FilenameUtils.concat("a/b", "../f"));
  +        assertEquals("a" + SEP + "c" + SEP + "g", 
FilenameUtils.concat("a/b/../c/", "f/../g/"));
  +        assertEquals("a" + SEP + "c" + SEP + "g", 
FilenameUtils.concat("a/b/../c", "f/../g"));
  +        
  +        assertEquals("a" + SEP + "c.txt" + SEP + "f", 
FilenameUtils.concat("a/c.txt", "f"));
  +        
  +        assertEquals(SEP + "f", FilenameUtils.concat("", "/f/"));
  +        assertEquals(SEP + "f", FilenameUtils.concat("", "/f"));
  +        assertEquals(SEP + "f", FilenameUtils.concat("a/", "/f/"));
  +        assertEquals(SEP + "f", FilenameUtils.concat("a", "/f"));
       }
   
       //-----------------------------------------------------------------------
  
  
  
  1.30      +71 -47    
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.29
  retrieving revision 1.30
  diff -u -r1.29 -r1.30
  --- FilenameUtils.java        27 Nov 2004 01:22:05 -0000      1.29
  +++ FilenameUtils.java        27 Nov 2004 17:00:51 -0000      1.30
  @@ -31,13 +31,28 @@
    * <li>the base name - file</li>
    * <li>the extension - txt</li>
    * </ul>
  - * The class only supports Unix and Windows style names.
  + * The class only supports Unix and Windows style names. Prefixes are 
matched as follows:
  + * <pre>
  + * Windows style:
  + * 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 style:
  + * 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>
  + * 
    * </p>
    * <h3>Origin of code</h3>
    * <ul>
    *   <li>Commons Utils</li>
    *   <li>Alexandria's FileUtils</li>
    *   <li>Avalon Excalibur's IO</li>
  + *   <li>Tomcat</li>
    * </ul>
    *
    * @author <a href="mailto:[EMAIL PROTECTED]">Kevin A. Burton</A>
  @@ -90,14 +105,15 @@
       /**
        * Instances should NOT be constructed in standard programming.
        */
  -    public FilenameUtils() { }
  +    public FilenameUtils() {
  +    }
   
       //-----------------------------------------------------------------------
       /**
        * Checks if the character is a separator.
        * 
        * @param ch  the character to check
  -     * @return true if it is a separators
  +     * @return true if it is a separator character
        */
       private static boolean isSeparator(char ch) {
           return (ch == UNIX_SEPARATOR) || (ch == WINDOWS_SEPARATOR);
  @@ -135,9 +151,10 @@
        * ~/foo/../bar         -->   ~/bar
        * ~/../bar             -->   null
        * </pre>
  +     * (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 too many ..'s.
  +     * @return the normalized String, or null if invalid
        */
       public static String normalize(String filename) {
           if (filename == null) {
  @@ -215,49 +232,53 @@
       }
   
       /**
  -     * Will concatenate 2 paths. Paths with <code>..</code> will be
  -     * properly handled. The path separator between the 2 paths is the
  -     * system default path separator.
  -     *
  -     * <p>Eg. on UNIX,<br />
  -     * <code>/a/b/c</code> + <code>d</code> = <code>/a/b/d</code><br />
  -     * <code>/a/b/c</code> + <code>../d</code> = <code>/a/d</code><br />
  -     * </p>
  -     *
  -     * <p>Eg. on Microsoft Windows,<br />
  -     * <code>C:\a\b\c</code> + <code>d</code> = <code>C:\a\b\d</code><br />
  -     * <code>C:\a\b\c</code> + <code>..\d</code> = <code>C:\a\d</code><br />
  -     * <code>/a/b/c</code> + <code>d</code> = <code>/a/b\d</code><br />
  -     * </p>
  -     *
  -     * Thieved from Tomcat sources...
  +     * Concatenates two paths 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 [EMAIL PROTECTED] 
#normalize(String)},
  +     * thus <code>..</code> is handled.
  +     * <p>
  +     * 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.
  +     * <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
  +     * </pre>
  +     * 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 [EMAIL PROTECTED] #getFullPath(String)} on the base path argument.
        *
  -     * @param lookupPath the base path to attach to
  -     * @param path path the second path to attach to the first
  -     * @return The concatenated paths, or null if error occurs
  -     */
  -     // TODO UNIX/Windows only. Is this a problem?
  -    public static String catPath(String lookupPath, String path) {
  -        // Cut off the last slash and everything beyond
  -        int index = indexOfLastSeparator(lookupPath);
  -        String lookup = lookupPath.substring(0, index);
  -        String pth = path;
  -
  -        // Deal with .. by chopping dirs off the lookup path
  -        while (pth.startsWith("../") || pth.startsWith("..\\")) {
  -            if (lookup.length() > 0) {
  -                index = indexOfLastSeparator(lookup);
  -                lookup = lookup.substring(0, index);
  -            } else {
  -                // More ..'s than dirs, return null
  -                return null;
  -            }
  -
  -            pth = pth.substring(3);
  +     * @param basePath  the base path to attach to, always treated as a path
  +     * @param pathToAdd  path the second path to attach to the first
  +     * @return the concatenated path, or null if invalid
  +     */
  +    public static String concat(String basePath, String pathToAdd) {
  +        int prefix = getPrefixLength(pathToAdd);
  +        if (prefix < 0) {
  +            return null;
  +        }
  +        if (prefix > 0) {
  +            return normalize(pathToAdd);
  +        }
  +        if (basePath == null) {
  +            return null;
  +        }
  +        int len = basePath.length();
  +        if (len == 0) {
  +            return normalize(pathToAdd);
  +        }
  +        char ch = basePath.charAt(len - 1);
  +        if (isSeparator(basePath.charAt(len - 1))) {
  +            return normalize(basePath + pathToAdd);
  +        } else {
  +            return normalize(basePath + '/' + pathToAdd);
           }
  -
  -        return new StringBuffer(lookup).
  -                append(File.separator).append(pth).toString();
       }
   
       //-----------------------------------------------------------------------
  @@ -338,8 +359,11 @@
               return 0;
           }
           char ch0 = filename.charAt(0);
  +        if (ch0 == ':') {
  +            return -1;
  +        }
           if (len == 1) {
  -            if (ch0 == '~' || ch0 == ':') {
  +            if (ch0 == '~') {
                   return -1;
               }
               return (isSeparator(ch0) ? 1 : 0);
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to