matches with the change in FileUtils.toURI recently done git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@349552 13f79535-47bb-0310-9956-ffa450edef68master
@@ -1,13 +1,18 @@ | |||
<project name="antclassloader-test" basedir="."> | |||
<property name="tmp.dir" location="tmp space"/> | |||
<!-- ant for germans --> | |||
<property name="tmp.dir.nonascii" value="ãnt"/> | |||
<property name="ext.dir.relative" value="ext"/> | |||
<property name="main.jar" location="${tmp.dir}/main.jar"/> | |||
<property name="ext.jar.relative" value="${ext.dir.relative}/ext.jar"/> | |||
<property name="ext.jar" location="${tmp.dir}/${ext.jar.relative}"/> | |||
<property name="build.sysclasspath" value="first"/> | |||
<property name="main.jar.nonascii" location="${tmp.dir.nonascii}/main.jar"/> | |||
<property name="ext.jar.nonascii" location="${tmp.dir.nonascii}/${ext.jar.relative}"/> | |||
<target name="setup" depends="setup.withspace,setup.nonascii"/> | |||
<target name="setup"> | |||
<target name="setup.withspace"> | |||
<mkdir dir="${tmp.dir}/${ext.dir.relative}"/> | |||
<jar destfile="${main.jar}" whenempty="create"> | |||
<manifest> | |||
@@ -16,10 +21,20 @@ | |||
</jar> | |||
<jar destfile="${ext.jar}"/> | |||
</target> | |||
<target name="setup.nonascii"> | |||
<mkdir dir="${tmp.dir.nonascii}/${ext.dir.relative}"/> | |||
<jar destfile="${main.jar.nonascii}" whenempty="create"> | |||
<manifest> | |||
<attribute name="Class-Path" value="${ext.jar.relative}"/> | |||
</manifest> | |||
</jar> | |||
<jar destfile="${ext.jar.nonascii}"/> | |||
</target> | |||
<target name="cleanup"> | |||
<delete dir="${tmp.dir}" quiet="true"/> | |||
<delete dir="${tmp.dir.nonascii}" quiet="true"/> | |||
</target> | |||
@@ -46,6 +46,7 @@ import org.apache.tools.ant.util.CollectionUtils; | |||
import org.apache.tools.ant.util.FileUtils; | |||
import org.apache.tools.ant.util.JavaEnvUtils; | |||
import org.apache.tools.ant.util.LoaderUtils; | |||
import org.apache.tools.ant.launch.Locator; | |||
/** | |||
* Used to load classes within ant with a different classpath from | |||
@@ -500,14 +501,7 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener { | |||
+ " loader", Project.MSG_VERBOSE); | |||
continue; | |||
} | |||
String decodedPath = null; | |||
// try catch block required because URLDecoder.decode throws | |||
// exception on JDK 1.2 | |||
try { | |||
decodedPath = URLDecoder.decode(libraryURL.getFile()); | |||
} catch (Exception exc) { | |||
throw new BuildException(exc); | |||
} | |||
String decodedPath = Locator.decodeUri(libraryURL.getFile()); | |||
File libraryFile = new File(decodedPath); | |||
if (libraryFile.exists() && !isInPath(libraryFile)) { | |||
addPathFile(libraryFile); | |||
@@ -21,6 +21,8 @@ import java.net.MalformedURLException; | |||
import java.net.URL; | |||
import java.io.File; | |||
import java.io.FilenameFilter; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.UnsupportedEncodingException; | |||
import java.text.CharacterIterator; | |||
import java.text.StringCharacterIterator; | |||
import java.util.Locale; | |||
@@ -32,6 +34,10 @@ import java.util.Locale; | |||
* @since Ant 1.6 | |||
*/ | |||
public final class Locator { | |||
/** | |||
* encoding used to represent URIs | |||
*/ | |||
public static String URI_ENCODING = "UTF-8"; | |||
/** | |||
* Not instantiable | |||
*/ | |||
@@ -96,6 +102,10 @@ public final class Locator { | |||
* <p>Swallows '%' that are not followed by two characters, | |||
* doesn't deal with non-ASCII characters.</p> | |||
* | |||
* @see <a href="http://www.w3.org/TR/xml11/#dt-sysid">dt-sysid</a> | |||
* which makes some mention of how | |||
* characters not supported by URI Reference syntax should be escaped. | |||
* | |||
* @param uri the URI designating a file in the local filesystem. | |||
* @return the local file system path for the file. | |||
* @since Ant 1.6 | |||
@@ -124,21 +134,30 @@ public final class Locator { | |||
&& Character.isLetter(uri.charAt(1)) && uri.lastIndexOf(':') > -1) { | |||
uri = uri.substring(1); | |||
} | |||
String path = decodeUri(uri); | |||
String path = null; | |||
try { | |||
path = decodeUri(uri); | |||
} catch (UnsupportedEncodingException exc) { | |||
// not sure whether this is clean, but this method is declared not to throw exceptions. | |||
throw new IllegalStateException("Could not convert URI to path", exc); | |||
} | |||
return path; | |||
} | |||
/** | |||
* Decodes an Uri with % characters. | |||
* The URI is escaped | |||
* @param uri String with the uri possibly containing % characters. | |||
* @return The decoded Uri | |||
* @throws UnsupportedEncodingException if UTF-8 is not available | |||
* @since Ant 1.7 | |||
*/ | |||
private static String decodeUri(String uri) { | |||
public static String decodeUri(String uri) throws UnsupportedEncodingException{ | |||
if (uri.indexOf('%') == -1) | |||
{ | |||
return uri; | |||
} | |||
StringBuffer sb = new StringBuffer(); | |||
ByteArrayOutputStream sb = new ByteArrayOutputStream(uri.length()); | |||
CharacterIterator iter = new StringCharacterIterator(uri); | |||
for (char c = iter.first(); c != CharacterIterator.DONE; | |||
c = iter.next()) { | |||
@@ -149,14 +168,14 @@ public final class Locator { | |||
char c2 = iter.next(); | |||
if (c2 != CharacterIterator.DONE) { | |||
int i2 = Character.digit(c2, 16); | |||
sb.append((char) ((i1 << 4) + i2)); | |||
sb.write((char) ((i1 << 4) + i2)); | |||
} | |||
} | |||
} else { | |||
sb.append(c); | |||
sb.write(c); | |||
} | |||
} | |||
String path = sb.toString(); | |||
String path = sb.toString("UTF-8"); | |||
return path; | |||
} | |||
@@ -1026,6 +1026,11 @@ public class FileUtils { | |||
* <p>This code encodes non ASCII characters too.</p> | |||
* | |||
* <p>The coding of the output is the same as what File.toURI().toASCIIString() produces</p> | |||
* | |||
* @see <a href="http://www.w3.org/TR/xml11/#dt-sysid">dt-sysid</a> | |||
* which makes some mention of how | |||
* characters not supported by URI Reference syntax should be escaped. | |||
* | |||
* @param path the path in the local file system. | |||
* @return the URI version of the local path. | |||
* @since Ant 1.6 | |||
@@ -1067,7 +1072,7 @@ public class FileUtils { | |||
byte[] bytes = null; | |||
byte b; | |||
try { | |||
bytes = path.substring(i).getBytes("UTF-8"); | |||
bytes = path.substring(i).getBytes(Locator.URI_ENCODING); | |||
} catch (java.io.UnsupportedEncodingException e) { | |||
// should never happen | |||
throw new BuildException(e); | |||
@@ -53,6 +53,16 @@ public class AntClassLoaderTest extends BuildFileTest { | |||
String path = myLoader.getClasspath(); | |||
assertEquals(mainjarstring + File.pathSeparator + extjarstring, path); | |||
} | |||
public void testJarWithManifestInNonAsciiDir() { | |||
String mainjarstring = getProject().getProperty("main.jar.nonascii"); | |||
String extjarstring = getProject().getProperty("ext.jar.nonascii"); | |||
Path myPath = new Path(getProject()); | |||
myPath.setLocation(new File(mainjarstring)); | |||
getProject().setUserProperty("build.sysclasspath","ignore"); | |||
AntClassLoader myLoader = getProject().createClassLoader(myPath); | |||
String path = myLoader.getClasspath(); | |||
assertEquals(mainjarstring + File.pathSeparator + extjarstring, path); | |||
} | |||
public void testCleanup() throws BuildException { | |||
Path path = new Path(p, "."); | |||
AntClassLoader loader = new AntClassLoader(p, path); | |||