You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by bo...@apache.org on 2002/11/18 15:31:53 UTC

cvs commit: jakarta-ant/src/testcases/org/apache/tools/ant/util FileUtilsTest.java

bodewig     2002/11/18 06:31:52

  Modified:    src/main/org/apache/tools/ant/helper ProjectHelperImpl.java
               src/main/org/apache/tools/ant/util FileUtils.java
               src/testcases/org/apache/tools/ant IncludeTest.java
               src/testcases/org/apache/tools/ant/util FileUtilsTest.java
  Added:       src/etc/testcases/core/include/with include.inc include.xml
                        relative.xml simple.xml
  Log:
  Don't stop with encoding # when creating URIs for the XML parser.
  Code heavily inspired by Xerces-J code.  This version is extremely
  simplified as it doesn't deal with non-ASCII characters for now.
  
  PR: 13679
  
  Revision  Changes    Path
  1.1                  jakarta-ant/src/etc/testcases/core/include/with
  
  Index: include.inc
  ===================================================================
  <target name="test1">
      <echo message="from included entity in &apos;with space&apos;"/>
  </target>
  
  
  
  1.1                  jakarta-ant/src/etc/testcases/core/include/with
  
  Index: include.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <!DOCTYPE project [
    <!ENTITY include SYSTEM "file:include.inc">
  ]>
  
  <project name="include-test" basedir="." default="test1">
      &include;
  </project>
  
  
  
  1.1                  jakarta-ant/src/etc/testcases/core/include/with
  
  Index: relative.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <!DOCTYPE project [
    <!ENTITY include SYSTEM "include.inc">
  ]>
  
  <project name="include-test" basedir="." default="test1">
      &include;
  </project>
  
  
  
  1.1                  jakarta-ant/src/etc/testcases/core/include/with
  
  Index: simple.xml
  ===================================================================
  <?xml version="1.0"?>
  <project name="include-test" basedir="." default="test1">
    <target name="test1">
      <echo message="from simple buildfile in &apos;with space&apos;"/>
    </target>
  </project>
  
  
  
  1.16      +9 -25     jakarta-ant/src/main/org/apache/tools/ant/helper/ProjectHelperImpl.java
  
  Index: ProjectHelperImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/helper/ProjectHelperImpl.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- ProjectHelperImpl.java	9 Sep 2002 10:34:48 -0000	1.15
  +++ ProjectHelperImpl.java	18 Nov 2002 14:31:52 -0000	1.16
  @@ -71,6 +71,7 @@
   import org.apache.tools.ant.TaskAdapter;
   import org.apache.tools.ant.TaskContainer;
   import org.apache.tools.ant.UnknownElement;
  +import org.apache.tools.ant.util.FileUtils;
   import org.apache.tools.ant.util.JAXPUtils;
   import org.xml.sax.AttributeList;
   import org.xml.sax.DocumentHandler;
  @@ -115,6 +116,10 @@
        * been placed outside of targets.</p>
        */
       private Target implicitTarget = new Target();
  +    /**
  +     * helper for path -> URI and URI -> path conversions.
  +     */
  +    private static FileUtils fu = FileUtils.newFileUtils();
   
       public ProjectHelperImpl() {
           implicitTarget.setName("");
  @@ -148,11 +153,7 @@
               }
   
   
  -            String uri = "file:" + buildFile.getAbsolutePath().replace('\\', '/');
  -            for (int index = uri.indexOf('#'); index != -1; index = uri.indexOf('#')) {
  -                uri = uri.substring(0, index) + "%23" + uri.substring(index + 1);
  -            }
  -
  +            String uri = fu.toURI(buildFile.getAbsolutePath());
               inputStream = new FileInputStream(buildFile);
               inputSource = new InputSource(inputStream);
               inputSource.setSystemId(uri);
  @@ -329,32 +330,15 @@
               helperImpl.project.log("resolving systemId: " + systemId, Project.MSG_VERBOSE);
   
               if (systemId.startsWith("file:")) {
  -                String path = systemId.substring(5);
  -                int index = path.indexOf("file:");
  -
  -                // we only have to handle these for backward compatibility
  -                // since they are in the FAQ.
  -                while (index != -1) {
  -                    path = path.substring(0, index) + path.substring(index + 5);
  -                    index = path.indexOf("file:");
  -                }
  -
  -                String entitySystemId = path;
  -                index = path.indexOf("%23");
  -                // convert these to #
  -                while (index != -1) {
  -                    path = path.substring(0, index) + "#" + path.substring(index + 3);
  -                    index = path.indexOf("%23");
  -                }
  +                String path = fu.fromURI(systemId);
   
                   File file = new File(path);
                   if (!file.isAbsolute()) {
  -                    file = new File(helperImpl.buildFileParent, path);
  +                    file = fu.resolveFile(helperImpl.buildFileParent, path);
                   }
  -
                   try {
                       InputSource inputSource = new InputSource(new FileInputStream(file));
  -                    inputSource.setSystemId("file:" + entitySystemId);
  +                    inputSource.setSystemId(fu.toURI(file.getAbsolutePath()));
                       return inputSource;
                   } catch (FileNotFoundException fne) {
                       helperImpl.project.log(file.getAbsolutePath() + " could not be found",
  
  
  
  1.31      +130 -16   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.30
  retrieving revision 1.31
  diff -u -r1.30 -r1.31
  --- FileUtils.java	31 Oct 2002 15:12:53 -0000	1.30
  +++ FileUtils.java	18 Nov 2002 14:31:52 -0000	1.31
  @@ -70,7 +70,9 @@
   import java.lang.reflect.Method;
   import java.net.MalformedURLException;
   import java.net.URL;
  +import java.text.CharacterIterator;
   import java.text.DecimalFormat;
  +import java.text.StringCharacterIterator;
   import java.util.Random;
   import java.util.Stack;
   import java.util.StringTokenizer;
  @@ -103,6 +105,34 @@
   
       private boolean onNetWare = Os.isFamily("netware");
   
  +    // for toURI
  +    private static boolean[] isSpecial = new boolean[256];
  +    private static char[] escapedChar1 = new char[256];
  +    private static char[] escapedChar2 = new char[256];
  +
  +
  +    // stolen from FilePathToURI of the Xerces-J team
  +    static {
  +        for (int i = 0; i <= 0x20; i++) {
  +            isSpecial[i] = true;
  +            escapedChar1[i] = Character.forDigit(i >> 4, 16);
  +            escapedChar2[i] = Character.forDigit(i & 0xf, 16);
  +        }
  +        isSpecial[0x7f] = true;
  +        escapedChar1[0x7f] = '7';
  +        escapedChar2[0x7f] = 'F';
  +        char[] escChs = {'<', '>', '#', '%', '"', '{', '}',
  +                         '|', '\\', '^', '~', '[', ']', '`'};
  +        int len = escChs.length;
  +        char ch;
  +        for (int i = 0; i < len; i++) {
  +            ch = escChs[i];
  +            isSpecial[ch] = true;
  +            escapedChar1[ch] = Character.forDigit(ch >> 4, 16);
  +            escapedChar2[ch] = Character.forDigit(ch & 0xf, 16);
  +        }
  +    }
  +
       /**
        * Factory method.
        */
  @@ -124,14 +154,11 @@
        *      formed.
        */
       public URL getFileURL(File file) throws MalformedURLException {
  -        String uri = "file:" + file.getAbsolutePath().replace('\\', '/');
  -        for (int i = uri.indexOf('#'); i != -1; i = uri.indexOf('#')) {
  -            uri = uri.substring(0, i) + "%23" + uri.substring(i + 1);
  -        }
  +        String path = file.getAbsolutePath();
           if (file.isDirectory()) {
  -            uri += "/";
  +            path += "/";
           }
  -        return new URL(uri);
  +        return new URL(toURI(path));
       }
   
       /**
  @@ -168,7 +195,7 @@
                    overwrite, false);
       }
   
  -     /**
  +    /**
        * Convienence method to copy a file from a source to a
        * destination specifying if token filtering must be used, if
        * source files may overwrite newer destination files and the
  @@ -342,12 +369,12 @@
                       } else {
                           in =
                               new BufferedReader(new InputStreamReader(
  -                                                 new FileInputStream(sourceFile),
  -                                                 encoding));
  +                                                                     new FileInputStream(sourceFile),
  +                                                                     encoding));
                           out =
                               new BufferedWriter(new OutputStreamWriter(
  -                                                 new FileOutputStream(destFile),
  -                                                 encoding));
  +                                                                      new FileOutputStream(destFile),
  +                                                                      encoding));
                       }
   
                       if (filterChainsAvailable) {
  @@ -555,8 +582,8 @@
           if (!onNetWare) {
               if (!path.startsWith(File.separator) &&
                   !(path.length() >= 2 &&
  -                   Character.isLetter(path.charAt(0)) &&
  -                   colon == 1)) {
  +                  Character.isLetter(path.charAt(0)) &&
  +                  colon == 1)) {
                   String msg = path + " is not an absolute path";
                   throw new BuildException(msg);
               }
  @@ -780,7 +807,7 @@
       public static final String readFully(Reader rdr, int bufferSize) throws IOException {
           if (bufferSize <= 0) {
               throw new IllegalArgumentException("Buffer size must be greater "
  -                + "than 0");
  +                                               + "than 0");
           }
           final char[] buffer = new char[bufferSize];
           int bufferLength = 0;
  @@ -791,7 +818,7 @@
               if (bufferLength != -1) {
                   if (textBuffer == null) {
                       textBuffer = new StringBuffer(
  -                                    new String(buffer, 0, bufferLength));
  +                                                  new String(buffer, 0, bufferLength));
                   } else {
                       textBuffer.append(new String(buffer, 0, bufferLength));
                   }
  @@ -875,5 +902,92 @@
               return p;
           }
       }
  +
  +    /**
  +     * Constructs a <code>file:</code> URI that represents the
  +     * external form of the given pathname.
  +     *
  +     * <p>Will be an absolute URI if the given path is absolute.</p>
  +     *
  +     * <p>This code doesn't handle non-ASCII characters properly.</p>
  +     *
  +     * @since Ant 1.6
  +     */
  +    public String toURI(String path) {
  +        StringBuffer sb = new StringBuffer("file:");
  +
  +        // catch exception if normalize thinks this is not an absolute path
  +        try {
  +            path = normalize(path).getAbsolutePath();
  +            sb.append("//");
  +        } catch (BuildException e) {
  +            // relative path
  +        }
  +        
  +        path = path.replace('\\', '/');
  +        CharacterIterator iter = new StringCharacterIterator(path);
  +        for (char c = iter.first(); c != CharacterIterator.DONE; 
  +             c = iter.next()) {
  +            if (isSpecial[c]) {
  +                sb.append('%');
  +                sb.append(escapedChar1[c]);
  +                sb.append(escapedChar2[c]);
  +            } else {
  +                sb.append(c);
  +            }
  +        }
  +        return sb.toString();
  +    }
  +
  +    /**
  +     * Constructs a file path from a <code>file:</code> URI.
  +     *
  +     * <p>Will be an absolute path if the given URI is absolute.</p>
  +     *
  +     * <p>Swallows '%' that are not followed by two characters,
  +     * doesn't deal with non-ASCII characters.</p>
  +     *
  +     * @since Ant 1.6
  +     */
  +    public String fromURI(String uri) {
  +        if (!uri.startsWith("file:")) {
  +            throw new IllegalArgumentException("Can only handle file: URIs");
  +        }
  +        if (uri.startsWith("file://")) {
  +            uri = uri.substring(7);
  +        } else {
  +            uri = uri.substring(5);
  +        }
  +
  +        uri = uri.replace('/', File.separatorChar);
  +        StringBuffer sb = new StringBuffer();
  +        CharacterIterator iter = new StringCharacterIterator(uri);
  +        for (char c = iter.first(); c != CharacterIterator.DONE; 
  +             c = iter.next()) {
  +            if (c == '%') {
  +                char c1 = iter.next();
  +                if (c1 != CharacterIterator.DONE) {
  +                    int i1 = Character.digit(c1, 16);
  +                    char c2 = iter.next();
  +                    if (c2 != CharacterIterator.DONE) {
  +                        int i2 = Character.digit(c2, 16);
  +                        sb.append((char) ((i1 << 4) + i2));
  +                    }
  +                }
  +            } else {
  +                sb.append(c);
  +            }
  +        }
  +
  +        String path = sb.toString();
  +        // catch exception if normalize thinks this is not an absolute path
  +        try {
  +            path = normalize(path).getAbsolutePath();
  +        } catch (BuildException e) {
  +            // relative path
  +        }
  +        return path;
  +    }
  +
   }
   
  
  
  
  1.5       +15 -0     jakarta-ant/src/testcases/org/apache/tools/ant/IncludeTest.java
  
  Index: IncludeTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/testcases/org/apache/tools/ant/IncludeTest.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- IncludeTest.java	9 Jul 2002 21:06:15 -0000	1.4
  +++ IncludeTest.java	18 Nov 2002 14:31:52 -0000	1.5
  @@ -145,4 +145,19 @@
           }
       }
   
  +    public void testWithSpaceInclude() { 
  +        configureProject("src/etc/testcases/core/include/with space/include.xml");
  +        expectLog("test1", "from included entity in 'with space'");
  +    }
  +    
  +    public void testWithSpaceSimple() { 
  +        configureProject("src/etc/testcases/core/include/with space/simple.xml");
  +        expectLog("test1", "from simple buildfile in 'with space'");
  +    }
  +    
  +    public void testWithSpaceRelative() { 
  +        configureProject("src/etc/testcases/core/include/with space/relative.xml");
  +        expectLog("test1", "from included entity in 'with space'");
  +    }
  +
   }
  
  
  
  1.12      +31 -0     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.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- FileUtilsTest.java	10 Jun 2002 06:19:32 -0000	1.11
  +++ FileUtilsTest.java	18 Nov 2002 14:31:52 -0000	1.12
  @@ -409,6 +409,37 @@
       }
   
       /**
  +     * test toUri
  +     */
  +    public void testToURI() {
  +        if (Os.isFamily("windows")) {
  +            assertEquals("file://C:/foo", fu.toURI("c:\\foo"));
  +        }
  +        assertEquals("file:///foo", fu.toURI("/foo"));
  +        assertEquals("file:./foo",  fu.toURI("./foo"));
  +        assertEquals("file:///foo", fu.toURI("\\foo"));
  +        assertEquals("file:./foo",  fu.toURI(".\\foo"));
  +        assertEquals("file:///foo%20bar", fu.toURI("/foo bar"));
  +        assertEquals("file:///foo%20bar", fu.toURI("\\foo bar"));
  +        assertEquals("file:///foo%23bar", fu.toURI("/foo#bar"));
  +        assertEquals("file:///foo%23bar", fu.toURI("\\foo#bar"));
  +    }
  +
  +    /**
  +     * test fromUri
  +     */
  +    public void testFromURI() {
  +        if (Os.isFamily("windows")) {
  +            assertEquals("C:\\foo", fu.fromURI("file://c:/foo"));
  +        }
  +        assertEquals(localize("/foo"), fu.fromURI("file:///foo"));
  +        assertEquals("." + File.separator + "foo", 
  +                     fu.fromURI("file:./foo"));
  +        assertEquals(localize("/foo bar"), fu.fromURI("file:///foo%20bar"));
  +        assertEquals(localize("/foo#bar"), fu.fromURI("file:///foo%23bar"));
  +    }
  +
  +    /**
        * adapt file separators to local conventions
        */
       private String localize(String path) {
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-ant/src/testcases/org/apache/tools/ant/util FileUtilsTest.java

Posted by Stefan Bodewig <bo...@apache.org>.
(1) I haven't tested it on Windows

(2) Some parts are hacky (catching an exception from normalize to
avoid redundant isAbsolute checks).

(3) It is incomplete (doesn't deal with non-ASCII, doesn't deal with
malformed escapes like %1Z in fromURI).

(4) It is in no way optimized for performance.

(5) May be a good place to hook in some reflection and take advantage
of Java 1.4's File.toURI and File(URI) API.

Reasons 1 - 3 are stopping me from merging it to the 1.5 branch.
There may be more good reasons to not do it.

Stefan

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>