git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@890827 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -32,6 +32,7 @@ import org.apache.tools.ant.types.resources.FileProvider; | |||
| import org.apache.tools.ant.types.resources.URLProvider; | |||
| import org.apache.tools.ant.util.FileUtils; | |||
| import org.apache.tools.ant.util.JAXPUtils; | |||
| import org.apache.tools.zip.ZipFile; | |||
| import org.xml.sax.Attributes; | |||
| import org.xml.sax.InputSource; | |||
| import org.xml.sax.Locator; | |||
| @@ -231,6 +232,7 @@ public class ProjectHelper2 extends ProjectHelper { | |||
| } | |||
| InputStream inputStream = null; | |||
| InputSource inputSource = null; | |||
| ZipFile zf = null; | |||
| try { | |||
| /** | |||
| @@ -243,16 +245,26 @@ public class ProjectHelper2 extends ProjectHelper { | |||
| uri = FILE_UTILS.toURI(buildFile.getAbsolutePath()); | |||
| inputStream = new FileInputStream(buildFile); | |||
| } else { | |||
| inputStream = url.openStream(); | |||
| uri = url.toString(); // ?? OK ?? | |||
| uri = url.toString(); | |||
| int pling = -1; | |||
| if (uri.startsWith("jar:file") | |||
| && (pling = uri.indexOf("!")) > -1) { | |||
| zf = new ZipFile(org.apache.tools.ant.launch.Locator | |||
| .fromJarURI(uri), "UTF-8"); | |||
| inputStream = | |||
| zf.getInputStream(zf.getEntry(uri.substring(pling + 1))); | |||
| } else { | |||
| inputStream = url.openStream(); | |||
| } | |||
| } | |||
| inputSource = new InputSource(inputStream); | |||
| if (uri != null) { | |||
| inputSource.setSystemId(uri); | |||
| } | |||
| project.log("parsing buildfile " + buildFileName + " with URI = " + uri, | |||
| Project.MSG_VERBOSE); | |||
| project.log("parsing buildfile " + buildFileName + " with URI = " | |||
| + uri + (zf != null ? " from a zip file" : ""), | |||
| Project.MSG_VERBOSE); | |||
| DefaultHandler hb = handler; | |||
| @@ -290,6 +302,7 @@ public class ProjectHelper2 extends ProjectHelper { | |||
| + exc.getMessage(), exc); | |||
| } finally { | |||
| FileUtils.close(inputStream); | |||
| ZipFile.closeQuietly(zf); | |||
| } | |||
| } | |||
| @@ -0,0 +1,60 @@ | |||
| /* | |||
| * Licensed to the Apache Software Foundation (ASF) under one or more | |||
| * contributor license agreements. See the NOTICE file distributed with | |||
| * this work for additional information regarding copyright ownership. | |||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | |||
| * (the "License"); you may not use this file except in compliance with | |||
| * the License. You may obtain a copy of the License at | |||
| * | |||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| * | |||
| */ | |||
| package org.apache.tools.ant.taskdefs; | |||
| import java.io.IOException; | |||
| import java.net.URL; | |||
| import java.util.Iterator; | |||
| import org.apache.tools.ant.Task; | |||
| import org.apache.tools.ant.types.Resource; | |||
| import org.apache.tools.ant.types.ResourceCollection; | |||
| import org.apache.tools.ant.types.resources.URLProvider; | |||
| import org.apache.tools.ant.types.resources.Union; | |||
| import org.apache.tools.ant.util.FileUtils; | |||
| /** | |||
| * Not a real task but used during tests. | |||
| * | |||
| * Closes the resources associated with an URL. In particular this is | |||
| * going to close the jars associated with a jar:file: URL - and it | |||
| * does so in a way that the Java VM still thinks it is open, so use | |||
| * it at your own risk. | |||
| */ | |||
| public class CloseResources extends Task { | |||
| private Union resources = new Union(); | |||
| public void add(ResourceCollection rc) { | |||
| resources.add(rc); | |||
| } | |||
| public void execute() { | |||
| for (Iterator it = resources.iterator(); it.hasNext(); ) { | |||
| Resource r = (Resource) it.next(); | |||
| URLProvider up = (URLProvider) r.as(URLProvider.class); | |||
| if (up != null) { | |||
| URL u = up.getURL(); | |||
| try { | |||
| FileUtils.close(u.openConnection()); | |||
| } catch (IOException ex) { | |||
| // ignore | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -22,12 +22,9 @@ import java.io.File; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.io.OutputStream; | |||
| import java.net.HttpURLConnection; | |||
| import java.net.URL; | |||
| import java.net.URLConnection; | |||
| import java.net.MalformedURLException; | |||
| import java.net.JarURLConnection; | |||
| import java.util.jar.JarFile; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.BuildException; | |||
| @@ -392,21 +389,10 @@ public class URLResource extends Resource implements URLProvider { | |||
| * | |||
| */ | |||
| private synchronized void close() { | |||
| if (conn != null) { | |||
| try { | |||
| if (conn instanceof JarURLConnection) { | |||
| JarURLConnection juc = (JarURLConnection) conn; | |||
| JarFile jf = juc.getJarFile(); | |||
| jf.close(); | |||
| jf = null; | |||
| } else if (conn instanceof HttpURLConnection) { | |||
| ((HttpURLConnection) conn).disconnect(); | |||
| } | |||
| } catch (IOException exc) { | |||
| //ignore | |||
| } finally { | |||
| conn = null; | |||
| } | |||
| try { | |||
| FileUtils.close(conn); | |||
| } finally { | |||
| conn = null; | |||
| } | |||
| } | |||
| @@ -27,7 +27,10 @@ import java.io.Reader; | |||
| import java.io.UnsupportedEncodingException; | |||
| import java.io.Writer; | |||
| import java.net.MalformedURLException; | |||
| import java.net.HttpURLConnection; | |||
| import java.net.JarURLConnection; | |||
| import java.net.URL; | |||
| import java.net.URLConnection; | |||
| import java.nio.channels.Channel; | |||
| import java.text.DecimalFormat; | |||
| import java.util.ArrayList; | |||
| @@ -38,6 +41,7 @@ import java.util.Random; | |||
| import java.util.Stack; | |||
| import java.util.StringTokenizer; | |||
| import java.util.Vector; | |||
| import java.util.jar.JarFile; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.PathTokenizer; | |||
| @@ -1444,6 +1448,30 @@ public class FileUtils { | |||
| } | |||
| } | |||
| /** | |||
| * Closes an URLConnection if its concrete implementation provides | |||
| * a way to close it that Ant knows of. | |||
| * | |||
| * @param conn connection, can be null | |||
| * @since Ant 1.8.0 | |||
| */ | |||
| public static void close(URLConnection conn) { | |||
| if (conn != null) { | |||
| try { | |||
| if (conn instanceof JarURLConnection) { | |||
| JarURLConnection juc = (JarURLConnection) conn; | |||
| JarFile jf = juc.getJarFile(); | |||
| jf.close(); | |||
| jf = null; | |||
| } else if (conn instanceof HttpURLConnection) { | |||
| ((HttpURLConnection) conn).disconnect(); | |||
| } | |||
| } catch (IOException exc) { | |||
| //ignore | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * Delete the file with {@link File#delete()} if the argument is not null. | |||
| * Do nothing on a null argument. | |||
| @@ -57,4 +57,16 @@ foo=bar | |||
| <au:assertLogContains text="type is url"/> | |||
| <au:assertLogContains text="foo is bar"/> | |||
| </target> | |||
| <target name="tearDown" depends="close, antunit-base.tearDown"/> | |||
| <target name="close"> | |||
| <taskdef name="close" | |||
| classname="org.apache.tools.ant.taskdefs.CloseResources"/> | |||
| <close> | |||
| <javaresource name="a/b/outer.xml"> | |||
| <classpath location="${output}/test.jar"/> | |||
| </javaresource> | |||
| </close> | |||
| </target> | |||
| </project> | |||
| @@ -0,0 +1,63 @@ | |||
| <?xml version="1.0"?> | |||
| <!-- | |||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||
| contributor license agreements. See the NOTICE file distributed with | |||
| this work for additional information regarding copyright ownership. | |||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||
| (the "License"); you may not use this file except in compliance with | |||
| the License. You may obtain a copy of the License at | |||
| http://www.apache.org/licenses/LICENSE-2.0 | |||
| Unless required by applicable law or agreed to in writing, software | |||
| distributed under the License is distributed on an "AS IS" BASIS, | |||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| See the License for the specific language governing permissions and | |||
| limitations under the License. | |||
| --> | |||
| <project default="antunit" xmlns:au="antlib:org.apache.ant.antunit"> | |||
| <import file="../antunit-base.xml" /> | |||
| <target name="setUp"> | |||
| <mkdir dir="${input}"/> | |||
| <echo file="${input}/foo.txt">Hello, world</echo> | |||
| <echo file="${input}/x.properties">a=b</echo> | |||
| <mkdir dir="${output}"/> | |||
| <jar destfile="${output}/javaresource-test.jar"> | |||
| <fileset dir="${input}"/> | |||
| </jar> | |||
| </target> | |||
| <target name="testReadFromFile" depends="setUp"> | |||
| <concat> | |||
| <javaresource name="foo.txt"> | |||
| <classpath location="${input}"/> | |||
| </javaresource> | |||
| </concat> | |||
| <au:assertLogContains text="Hello, world"/> | |||
| <loadproperties> | |||
| <javaresource name="x.properties"> | |||
| <classpath location="${input}"/> | |||
| </javaresource> | |||
| </loadproperties> | |||
| <au:assertPropertyEquals name="a" value="b"/> | |||
| </target> | |||
| <target name="testReadFromJar" depends="setUp"> | |||
| <delete dir="${input}"/> | |||
| <concat> | |||
| <javaresource name="foo.txt"> | |||
| <classpath location="${output}/javaresource-test.jar"/> | |||
| </javaresource> | |||
| </concat> | |||
| <au:assertLogContains text="Hello, world"/> | |||
| <loadproperties> | |||
| <javaresource name="x.properties"> | |||
| <classpath location="${output}/javaresource-test.jar"/> | |||
| </javaresource> | |||
| </loadproperties> | |||
| <au:assertPropertyEquals name="a" value="b"/> | |||
| </target> | |||
| </project> | |||