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="."> | <project name="antclassloader-test" basedir="."> | ||||
| <property name="tmp.dir" location="tmp space"/> | <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="ext.dir.relative" value="ext"/> | ||||
| <property name="main.jar" location="${tmp.dir}/main.jar"/> | <property name="main.jar" location="${tmp.dir}/main.jar"/> | ||||
| <property name="ext.jar.relative" value="${ext.dir.relative}/ext.jar"/> | <property name="ext.jar.relative" value="${ext.dir.relative}/ext.jar"/> | ||||
| <property name="ext.jar" location="${tmp.dir}/${ext.jar.relative}"/> | <property name="ext.jar" location="${tmp.dir}/${ext.jar.relative}"/> | ||||
| <property name="build.sysclasspath" value="first"/> | <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}"/> | <mkdir dir="${tmp.dir}/${ext.dir.relative}"/> | ||||
| <jar destfile="${main.jar}" whenempty="create"> | <jar destfile="${main.jar}" whenempty="create"> | ||||
| <manifest> | <manifest> | ||||
| @@ -16,10 +21,20 @@ | |||||
| </jar> | </jar> | ||||
| <jar destfile="${ext.jar}"/> | <jar destfile="${ext.jar}"/> | ||||
| </target> | </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"> | <target name="cleanup"> | ||||
| <delete dir="${tmp.dir}" quiet="true"/> | <delete dir="${tmp.dir}" quiet="true"/> | ||||
| <delete dir="${tmp.dir.nonascii}" quiet="true"/> | |||||
| </target> | </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.FileUtils; | ||||
| import org.apache.tools.ant.util.JavaEnvUtils; | import org.apache.tools.ant.util.JavaEnvUtils; | ||||
| import org.apache.tools.ant.util.LoaderUtils; | 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 | * 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); | + " loader", Project.MSG_VERBOSE); | ||||
| continue; | 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); | File libraryFile = new File(decodedPath); | ||||
| if (libraryFile.exists() && !isInPath(libraryFile)) { | if (libraryFile.exists() && !isInPath(libraryFile)) { | ||||
| addPathFile(libraryFile); | addPathFile(libraryFile); | ||||
| @@ -21,6 +21,8 @@ import java.net.MalformedURLException; | |||||
| import java.net.URL; | import java.net.URL; | ||||
| import java.io.File; | import java.io.File; | ||||
| import java.io.FilenameFilter; | import java.io.FilenameFilter; | ||||
| import java.io.ByteArrayOutputStream; | |||||
| import java.io.UnsupportedEncodingException; | |||||
| import java.text.CharacterIterator; | import java.text.CharacterIterator; | ||||
| import java.text.StringCharacterIterator; | import java.text.StringCharacterIterator; | ||||
| import java.util.Locale; | import java.util.Locale; | ||||
| @@ -32,6 +34,10 @@ import java.util.Locale; | |||||
| * @since Ant 1.6 | * @since Ant 1.6 | ||||
| */ | */ | ||||
| public final class Locator { | public final class Locator { | ||||
| /** | |||||
| * encoding used to represent URIs | |||||
| */ | |||||
| public static String URI_ENCODING = "UTF-8"; | |||||
| /** | /** | ||||
| * Not instantiable | * Not instantiable | ||||
| */ | */ | ||||
| @@ -96,6 +102,10 @@ public final class Locator { | |||||
| * <p>Swallows '%' that are not followed by two characters, | * <p>Swallows '%' that are not followed by two characters, | ||||
| * doesn't deal with non-ASCII characters.</p> | * 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. | * @param uri the URI designating a file in the local filesystem. | ||||
| * @return the local file system path for the file. | * @return the local file system path for the file. | ||||
| * @since Ant 1.6 | * @since Ant 1.6 | ||||
| @@ -124,21 +134,30 @@ public final class Locator { | |||||
| && Character.isLetter(uri.charAt(1)) && uri.lastIndexOf(':') > -1) { | && Character.isLetter(uri.charAt(1)) && uri.lastIndexOf(':') > -1) { | ||||
| uri = uri.substring(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; | return path; | ||||
| } | } | ||||
| /** | /** | ||||
| * Decodes an Uri with % characters. | * Decodes an Uri with % characters. | ||||
| * The URI is escaped | |||||
| * @param uri String with the uri possibly containing % characters. | * @param uri String with the uri possibly containing % characters. | ||||
| * @return The decoded Uri | * @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) | if (uri.indexOf('%') == -1) | ||||
| { | { | ||||
| return uri; | return uri; | ||||
| } | } | ||||
| StringBuffer sb = new StringBuffer(); | |||||
| ByteArrayOutputStream sb = new ByteArrayOutputStream(uri.length()); | |||||
| CharacterIterator iter = new StringCharacterIterator(uri); | CharacterIterator iter = new StringCharacterIterator(uri); | ||||
| for (char c = iter.first(); c != CharacterIterator.DONE; | for (char c = iter.first(); c != CharacterIterator.DONE; | ||||
| c = iter.next()) { | c = iter.next()) { | ||||
| @@ -149,14 +168,14 @@ public final class Locator { | |||||
| char c2 = iter.next(); | char c2 = iter.next(); | ||||
| if (c2 != CharacterIterator.DONE) { | if (c2 != CharacterIterator.DONE) { | ||||
| int i2 = Character.digit(c2, 16); | int i2 = Character.digit(c2, 16); | ||||
| sb.append((char) ((i1 << 4) + i2)); | |||||
| sb.write((char) ((i1 << 4) + i2)); | |||||
| } | } | ||||
| } | } | ||||
| } else { | } else { | ||||
| sb.append(c); | |||||
| sb.write(c); | |||||
| } | } | ||||
| } | } | ||||
| String path = sb.toString(); | |||||
| String path = sb.toString("UTF-8"); | |||||
| return path; | return path; | ||||
| } | } | ||||
| @@ -1026,6 +1026,11 @@ public class FileUtils { | |||||
| * <p>This code encodes non ASCII characters too.</p> | * <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> | * <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. | * @param path the path in the local file system. | ||||
| * @return the URI version of the local path. | * @return the URI version of the local path. | ||||
| * @since Ant 1.6 | * @since Ant 1.6 | ||||
| @@ -1067,7 +1072,7 @@ public class FileUtils { | |||||
| byte[] bytes = null; | byte[] bytes = null; | ||||
| byte b; | byte b; | ||||
| try { | try { | ||||
| bytes = path.substring(i).getBytes("UTF-8"); | |||||
| bytes = path.substring(i).getBytes(Locator.URI_ENCODING); | |||||
| } catch (java.io.UnsupportedEncodingException e) { | } catch (java.io.UnsupportedEncodingException e) { | ||||
| // should never happen | // should never happen | ||||
| throw new BuildException(e); | throw new BuildException(e); | ||||
| @@ -53,6 +53,16 @@ public class AntClassLoaderTest extends BuildFileTest { | |||||
| String path = myLoader.getClasspath(); | String path = myLoader.getClasspath(); | ||||
| assertEquals(mainjarstring + File.pathSeparator + extjarstring, path); | 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 { | public void testCleanup() throws BuildException { | ||||
| Path path = new Path(p, "."); | Path path = new Path(p, "."); | ||||
| AntClassLoader loader = new AntClassLoader(p, path); | AntClassLoader loader = new AntClassLoader(p, path); | ||||