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 'with space'"/>
</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 'with space'"/>
</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>