ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bode...@apache.org
Subject cvs commit: jakarta-ant/src/testcases/org/apache/tools/ant/util FileUtilsTest.java
Date Wed, 08 Aug 2001 16:13:08 GMT
bodewig     01/08/08 09:13:08

  Modified:    src/main/org/apache/tools/ant Project.java
               src/main/org/apache/tools/ant/taskdefs XSLTProcess.java
               src/main/org/apache/tools/ant/util FileUtils.java
               src/testcases/org/apache/tools/ant ProjectTest.java
               src/testcases/org/apache/tools/ant/util FileUtilsTest.java
  Log:
  Move resolveFile methods to FileUtils, add a normalize method there.
  
  Make sure Ant normalizes whatever it takes as its basedir - since
  we've dropped canonicalPath
  
  ant -f foo.xml
  
  and
  
  ant -f ./foo.xml
  
  would have given different results (the . needed to be stripped).
  
  Revision  Changes    Path
  1.73      +6 -56     jakarta-ant/src/main/org/apache/tools/ant/Project.java
  
  Index: Project.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/Project.java,v
  retrieving revision 1.72
  retrieving revision 1.73
  diff -u -r1.72 -r1.73
  --- Project.java	2001/08/07 11:43:32	1.72
  +++ Project.java	2001/08/08 16:13:08	1.73
  @@ -339,11 +339,12 @@
       }
   
       public void setBaseDir(File baseDir) throws BuildException {
  +        baseDir = fileUtils.normalize(baseDir.getAbsolutePath());
           if (!baseDir.exists()) 
               throw new BuildException("Basedir " + baseDir.getAbsolutePath() + " does not
exist");
           if (!baseDir.isDirectory()) 
               throw new BuildException("Basedir " + baseDir.getAbsolutePath() + " is not
a directory");
  -        this.baseDir = new File(baseDir.getAbsolutePath());
  +        this.baseDir = baseDir;
           setProperty( "basedir", this.baseDir.getPath());
           String msg = "Project base dir set to: " + this.baseDir;
           log(msg, MSG_VERBOSE);
  @@ -594,66 +595,15 @@
        *
        * <p>If fileName is a relative file name, resolve it relative to
        * rootDir.</p>
  +     *
  +     * @deprecated
        */
       public File resolveFile(String fileName, File rootDir) {
  -        fileName = fileName.replace('/', File.separatorChar).replace('\\', File.separatorChar);
  -
  -        // deal with absolute files
  -        if (fileName.startsWith(File.separator)) {
  -            return new File(fileName);
  -        }
  -
  -        // Eliminate consecutive slashes after the drive spec
  -        if (fileName.length() >= 2 &&
  -            Character.isLetter(fileName.charAt(0)) &&
  -            fileName.charAt(1) == ':') {
  -            char[] ca = fileName.replace('/', '\\').toCharArray();
  -            char c;
  -            StringBuffer sb = new StringBuffer();
  -
  -            for (int i = 0; i < ca.length; i++) {
  -                if ((ca[i] != '\\') ||
  -                    (ca[i] == '\\' &&
  -                        i > 0 &&
  -                        ca[i - 1] != '\\')) {
  -                    if (i == 0 &&
  -                        Character.isLetter(ca[i]) &&
  -                        i < ca.length - 1 &&
  -                        ca[i + 1] == ':') {
  -                        c = Character.toUpperCase(ca[i]);
  -                    } else {
  -                        c = ca[i];
  -                    }
  -
  -                    sb.append(c);
  -                }
  -            }
  -
  -            return new File(sb.toString());
  -        }
  -
  -        File file = new File(rootDir.getAbsolutePath());
  -        StringTokenizer tok = new StringTokenizer(fileName, File.separator, false);
  -        while (tok.hasMoreTokens()) {
  -            String part = tok.nextToken();
  -            if (part.equals("..")) {
  -                String parentFile = file.getParent();
  -                if (parentFile == null) {
  -                    throw new BuildException("The file or path you specified (" + fileName
+ ") is invalid relative to " + rootDir.getAbsolutePath());
  -                }
  -                file = new File(parentFile);
  -            } else if (part.equals(".")) {
  -                // Do nothing here
  -            } else {
  -                file = new File(file, part);
  -            }
  -        }
  -
  -        return new File(file.getAbsolutePath());
  +        return fileUtils.resolveFile(rootDir, fileName);
       }
   
       public File resolveFile(String fileName) {
  -        return resolveFile(fileName, baseDir);
  +        return fileUtils.resolveFile(baseDir, fileName);
       }
   
       /**
  
  
  
  1.23      +7 -3      jakarta-ant/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java
  
  Index: XSLTProcess.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- XSLTProcess.java	2001/06/22 07:24:17	1.22
  +++ XSLTProcess.java	2001/08/08 16:13:08	1.23
  @@ -63,6 +63,7 @@
   import org.apache.tools.ant.*;
   import org.apache.tools.ant.types.Path;
   import org.apache.tools.ant.types.Reference;
  +import org.apache.tools.ant.util.FileUtils;
   
   
   /**
  @@ -87,7 +88,7 @@
    * @author <a href="mailto:rubys@us.ibm.com">Sam Ruby</a>
    * @author <a href="mailto:russgold@acm.org">Russell Gold</a>
    * @author <a href="stefan.bodewig@epost.de">Stefan Bodewig</a>
  - * @version $Revision: 1.22 $ $Date: 2001/06/22 07:24:17 $
  + * @version $Revision: 1.23 $ $Date: 2001/08/08 16:13:08 $
    */
   public class XSLTProcess extends MatchingTask {
   
  @@ -111,10 +112,13 @@
   
       private boolean force = false;
   
  +    private FileUtils fileUtils;
  +
       /**
        * Creates a new XSLTProcess Task.
        **/
       public XSLTProcess() {
  +        fileUtils = FileUtils.newFileUtils();
       } //-- XSLTProcess
   
       /**
  @@ -137,9 +141,9 @@
           liaison = getLiaison();
           log("Using "+liaison.getClass().toString(), Project.MSG_VERBOSE);
   
  -        File stylesheet = project.resolveFile(xslFile, project.getBaseDir());
  +        File stylesheet = project.resolveFile(xslFile);
           if (!stylesheet.exists()) {
  -            stylesheet = project.resolveFile(xslFile, baseDir);
  +            stylesheet = fileUtils.resolveFile(baseDir, xslFile);
               /*
                * shouldn't throw out deprecation warnings before we know,
                * the wrong version has been used.
  
  
  
  1.3       +172 -7    jakarta-ant/src/main/org/apache/tools/ant/util/FileUtils.java
  
  Index: FileUtils.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/util/FileUtils.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- FileUtils.java	2001/08/07 05:49:48	1.2
  +++ FileUtils.java	2001/08/08 16:13:08	1.3
  @@ -56,22 +56,22 @@
   
   import java.io.*;
   import java.lang.reflect.Method;
  +import java.util.StringTokenizer;
  +import java.util.Stack;
   
   import org.apache.tools.ant.BuildException; 
   import org.apache.tools.ant.Project; 
   import org.apache.tools.ant.types.FilterSet; 
   
   /**
  - * Central representation of an Ant project. This class defines a
  - * Ant project with all of it's targets and tasks. It also provides
  - * the mechanism to kick off a build using a particular target name.
  - * <p>
  - * This class also encapsulates methods which allow Files to be refered
  - * to using abstract path names which are translated to native system
  - * file paths at runtime as well as defining various project properties.
  + * This class also encapsulates methods which allow Files to be
  + * refered to using abstract path names which are translated to native
  + * system file paths at runtime as well as copying files or setting
  + * there last modification time.
    *
    * @author duncan@x180.com
    * @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
  + * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> 
    */
    
   public class FileUtils {
  @@ -292,5 +292,170 @@
           }
       }
   
  +    /**
  +     * Interpret the filename as a file relative to the given file -
  +     * unless the filename already represents an absolute filename.
  +     *
  +     * @param file the "reference" file for relative paths. This
  +     * instance must be an absolute file and must not contain
  +     * &quot;./&quot; or &quot;../&quot; sequences (same for \ instead
  +     * of /).
  +     * @param filename a file name
  +     *
  +     * @return an absolute file that doesn't contain &quot;./&quot; or
  +     * &quot;../&quot; sequences and uses the correct separator for
  +     * the current platform.
  +     */
  +    public File resolveFile(File file, String filename) {
  +        filename = filename.replace('/', File.separatorChar)
  +            .replace('\\', File.separatorChar);
  +
  +        // deal with absolute files
  +        if (filename.startsWith(File.separator) ||
  +
  +            (filename.length() >= 2 &&
  +             Character.isLetter(filename.charAt(0)) &&
  +             filename.charAt(1) == ':')
  +
  +            ) {
  +            return normalize(filename);
  +        }
  +
  +        if (filename.length() >= 2 &&
  +            Character.isLetter(filename.charAt(0)) &&
  +            filename.charAt(1) == ':') {
  +            return normalize(filename);
  +        }
  +
  +        File helpFile = new File(file.getAbsolutePath());
  +        StringTokenizer tok = new StringTokenizer(filename, File.separator);
  +        while (tok.hasMoreTokens()) {
  +            String part = tok.nextToken();
  +            if (part.equals("..")) {
  +                String parentFile = helpFile.getParent();
  +                if (parentFile == null) {
  +                    String msg = "The file or path you specified ("
  +                        + filename + ") is invalid relative to " 
  +                        + file.getPath();
  +                    throw new BuildException(msg);
  +                }
  +                helpFile = new File(parentFile);
  +            } else if (part.equals(".")) {
  +                // Do nothing here
  +            } else {
  +                helpFile = new File(helpFile, part);
  +            }
  +        }
  +
  +        return new File(helpFile.getAbsolutePath());
  +    }
  +
  +    /**
  +     * &quot;normalize&quot; the given absolute path.
  +     *
  +     * <p>This includes:
  +     * <ul>
  +     *   <li>Uppercase the drive letter if there is one.</li>
  +     *   <li>Remove redundant slashes after the drive spec.</li>
  +     *   <li>resolve all ./, .\, ../ and ..\ sequences.</li>
  +     *   <li>DOS style paths that start with a drive letter will have
  +     *     \ as the separator.</li> 
  +     * </ul>
  +     */
  +    public File normalize(String path) {
  +        String orig = path;
  +
  +        path = path.replace('/', File.separatorChar)
  +            .replace('\\', File.separatorChar);
  +
  +        // make sure we are dealing with an absolute path
  +        if (!path.startsWith(File.separator) &&
  +            ! (path.length() >= 2 &&
  +               Character.isLetter(path.charAt(0)) &&
  +               path.charAt(1) == ':')
  +            ) {             
  +            String msg = path + " is not an absolute path";
  +            throw new BuildException(msg);
  +        }
  +            
  +        boolean dosWithDrive = false;
  +        String root = null;
  +        // Eliminate consecutive slashes after the drive spec
  +        if (path.length() >= 2 &&
  +            Character.isLetter(path.charAt(0)) &&
  +            path.charAt(1) == ':') {
  +
  +            dosWithDrive = true;
  +
  +            char[] ca = path.replace('/', '\\').toCharArray();
  +            StringBuffer sb = new StringBuffer();
  +            sb.append(Character.toUpperCase(ca[0])).append(':');
  +
  +            for (int i = 2; i < ca.length; i++) {
  +                if ((ca[i] != '\\') ||
  +                    (ca[i] == '\\' && ca[i - 1] != '\\')
  +                    ) {
  +                    sb.append(ca[i]);
  +                }
  +            }
  +
  +            path = sb.toString().replace('\\', File.separatorChar);
  +            if (path.length() == 2) {
  +                root = path;
  +                path = "";
  +            } else {
  +                root = path.substring(0, 3);
  +                path = path.substring(3);
  +            }
  +            
  +        } else {
  +            if (path.length() == 1) {
  +                root = File.separator;
  +                path = "";
  +            } else if (path.charAt(1) == File.separatorChar) {
  +                // UNC drive
  +                root = File.separator+File.separator;
  +                path = path.substring(2);
  +            } else {
  +                root = File.separator;
  +                path = path.substring(1);
  +            }
  +        }
  +
  +        Stack s = new Stack();
  +        s.push(root);
  +        StringTokenizer tok = new StringTokenizer(path, File.separator);
  +        while (tok.hasMoreTokens()) {
  +            String thisToken = tok.nextToken();
  +            if (".".equals(thisToken)) {
  +                continue;
  +            } else if ("..".equals(thisToken)) {
  +                if (s.size() < 2) {
  +                    throw new BuildException("Cannot resolve path "+orig);
  +                } else {
  +                    s.pop();
  +                }
  +            } else { // plain component
  +                s.push(thisToken);
  +            }
  +        }
  +
  +        StringBuffer sb = new StringBuffer();
  +        for (int i=0; i<s.size(); i++) {
  +            if (i > 1) {
  +                // not before the filesystem root and not after it, since root
  +                // already contains one
  +                sb.append(File.separatorChar);
  +            }
  +            sb.append(s.elementAt(i));
  +        }
  +        
  +
  +        path = sb.toString();
  +        if (dosWithDrive) {
  +            path = path.replace('/', '\\');
  +        }
  +        return new File(path);
  +    }
   }
   
  
  
  
  1.6       +3 -0      jakarta-ant/src/testcases/org/apache/tools/ant/ProjectTest.java
  
  Index: ProjectTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/testcases/org/apache/tools/ant/ProjectTest.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ProjectTest.java	2001/08/08 12:02:15	1.5
  +++ ProjectTest.java	2001/08/08 16:13:08	1.6
  @@ -93,6 +93,9 @@
           assert("Path", p.createDataType("path") instanceof Path);
       }
   
  +    /**
  +     * This test has been a starting point for moving the code to FileUtils.
  +     */
       public void testResolveFile() {
           /*
            * Start with simple absolute file names.
  
  
  
  1.2       +140 -1    jakarta-ant/src/testcases/org/apache/tools/ant/util/FileUtilsTest.java
  
  Index: FileUtilsTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/testcases/org/apache/tools/ant/util/FileUtilsTest.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- FileUtilsTest.java	2001/08/08 08:30:49	1.1
  +++ FileUtilsTest.java	2001/08/08 16:13:08	1.2
  @@ -58,6 +58,8 @@
   
   import junit.framework.TestCase;
   
  +import org.apache.tools.ant.BuildException;
  +
   /**
    * Tests for org.apache.tools.ant.util.FileUtils.
    *
  @@ -65,12 +67,19 @@
    */
   public class FileUtilsTest extends TestCase {
   
  +    private FileUtils fu;
       private File removeThis;
  +    private String root;
   
       public FileUtilsTest(String name) {
           super(name);
       }
   
  +    public void setUp() {
  +        fu = FileUtils.newFileUtils();
  +        root = new File(File.separator).getAbsolutePath();
  +    }
  +
       public void tearDown() {
           if (removeThis != null && removeThis.exists()) {
               removeThis.delete();
  @@ -78,7 +87,6 @@
       }
   
       public void testSetLastModified() throws IOException {
  -        FileUtils fu = FileUtils.newFileUtils();
           removeThis = new File("dummy");
           FileOutputStream fos = new FileOutputStream(removeThis);
           fos.write(new byte[0]);
  @@ -125,4 +133,135 @@
           }
       }
   
  +    public void testResolveFile() {
  +        /*
  +         * Start with simple absolute file names.
  +         */
  +        assertEquals(File.separator, 
  +                     fu.resolveFile(null, "/").getPath());
  +        assertEquals(File.separator, 
  +                     fu.resolveFile(null, "\\").getPath());
  +
  +        /*
  +         * throw in drive letters
  +         */
  +        String driveSpec = "C:";
  +        assertEquals(driveSpec + "\\", 
  +                     fu.resolveFile(null, driveSpec + "/").getPath());
  +        assertEquals(driveSpec + "\\", 
  +                     fu.resolveFile(null, driveSpec + "\\").getPath());
  +        String driveSpecLower = "c:";
  +        assertEquals(driveSpec + "\\", 
  +                     fu.resolveFile(null, driveSpecLower + "/").getPath());
  +        assertEquals(driveSpec + "\\", 
  +                     fu.resolveFile(null, driveSpecLower + "\\").getPath());
  +        /*
  +         * promised to eliminate consecutive slashes after drive letter.
  +         */
  +        assertEquals(driveSpec + "\\", 
  +                     fu.resolveFile(null, driveSpec + "/////").getPath());
  +        assertEquals(driveSpec + "\\", 
  +                     fu.resolveFile(null, driveSpec + "\\\\\\\\\\\\").getPath());
  +
  +        /*
  +         * Now test some relative file name magic.
  +         */
  +        assertEquals(localize("/1/2/3/4"),
  +                     fu.resolveFile(new File(localize("/1/2/3")), "4").getPath());
  +        assertEquals(localize("/1/2/3/4"),
  +                     fu.resolveFile(new File(localize("/1/2/3")), "./4").getPath());
  +        assertEquals(localize("/1/2/3/4"),
  +                     fu.resolveFile(new File(localize("/1/2/3")), ".\\4").getPath());
  +        assertEquals(localize("/1/2/3/4"),
  +                     fu.resolveFile(new File(localize("/1/2/3")), "./.\\4").getPath());
  +        assertEquals(localize("/1/2/3/4"),
  +                     fu.resolveFile(new File(localize("/1/2/3")), "../3/4").getPath());
  +        assertEquals(localize("/1/2/3/4"),
  +                     fu.resolveFile(new File(localize("/1/2/3")), "..\\3\\4").getPath());
  +        assertEquals(localize("/1/2/3/4"),
  +                     fu.resolveFile(new File(localize("/1/2/3")), "../../5/.././2/./3/6/../4").getPath());
  +        assertEquals(localize("/1/2/3/4"),
  +                     fu.resolveFile(new File(localize("/1/2/3")), "..\\../5/..\\./2/./3/6\\../4").getPath());
  +
  +        try {
  +            fu.resolveFile(new File(localize("/1")), "../../b");
  +            fail("successfully crawled beyond the filesystem root");
  +        } catch (BuildException e) {
  +            // Expected Exception caught
  +        }
  +
  +    }
  +
  +    public void testNormalize() {
  +        /*
  +         * Start with simple absolute file names.
  +         */
  +        assertEquals(File.separator, 
  +                     fu.normalize("/").getPath());
  +        assertEquals(File.separator, 
  +                     fu.normalize("\\").getPath());
  +
  +        /*
  +         * throw in drive letters
  +         */
  +        String driveSpec = "C:";
  +        assertEquals(driveSpec + "\\", 
  +                     fu.normalize(driveSpec + "/").getPath());
  +        assertEquals(driveSpec + "\\", 
  +                     fu.normalize(driveSpec + "\\").getPath());
  +        String driveSpecLower = "c:";
  +        assertEquals(driveSpec + "\\", 
  +                     fu.normalize(driveSpecLower + "/").getPath());
  +        assertEquals(driveSpec + "\\", 
  +                     fu.normalize(driveSpecLower + "\\").getPath());
  +        /*
  +         * promised to eliminate consecutive slashes after drive letter.
  +         */
  +        assertEquals(driveSpec + "\\", 
  +                     fu.normalize(driveSpec + "/////").getPath());
  +        assertEquals(driveSpec + "\\", 
  +                     fu.normalize(driveSpec + "\\\\\\\\\\\\").getPath());
  +
  +        /*
  +         * Now test some relative file name magic.
  +         */
  +        assertEquals(localize("/1/2/3/4"),
  +                     fu.normalize(localize("/1/2/3/4")).getPath());
  +        assertEquals(localize("/1/2/3/4"),
  +                     fu.normalize(localize("/1/2/3/./4")).getPath());
  +        assertEquals(localize("/1/2/3/4"),
  +                     fu.normalize(localize("/1/2/3/.\\4")).getPath());
  +        assertEquals(localize("/1/2/3/4"),
  +                     fu.normalize(localize("/1/2/3/./.\\4")).getPath());
  +        assertEquals(localize("/1/2/3/4"),
  +                     fu.normalize(localize("/1/2/3/../3/4")).getPath());
  +        assertEquals(localize("/1/2/3/4"),
  +                     fu.normalize(localize("/1/2/3/..\\3\\4")).getPath());
  +        assertEquals(localize("/1/2/3/4"),
  +                     fu.normalize(localize("/1/2/3/../../5/.././2/./3/6/../4")).getPath());
  +        assertEquals(localize("/1/2/3/4"),
  +                     fu.normalize(localize("/1/2/3/..\\../5/..\\./2/./3/6\\../4")).getPath());
  +
  +        try {
  +            fu.normalize("foo");
  +            fail("foo is not an absolute path");
  +        } catch (BuildException e) {
  +            // Expected exception caught
  +        }
  +        
  +        try {
  +            fu.normalize(localize("/1/../../b"));
  +            fail("successfully crawled beyond the filesystem root");
  +        } catch (BuildException e) {
  +            // Expected exception caught
  +        }
  +    }
  +
  +    /**
  +     * adapt file separators to local conventions
  +     */
  +    private String localize(String path) {
  +        path = root + path.substring(1);
  +        return path.replace('\\', File.separatorChar).replace('/', File.separatorChar);
  +    }
   }
  
  
  

Mime
View raw message