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.types.resources.URLProvider; | ||||
| import org.apache.tools.ant.util.FileUtils; | import org.apache.tools.ant.util.FileUtils; | ||||
| import org.apache.tools.ant.util.JAXPUtils; | import org.apache.tools.ant.util.JAXPUtils; | ||||
| import org.apache.tools.zip.ZipFile; | |||||
| import org.xml.sax.Attributes; | import org.xml.sax.Attributes; | ||||
| import org.xml.sax.InputSource; | import org.xml.sax.InputSource; | ||||
| import org.xml.sax.Locator; | import org.xml.sax.Locator; | ||||
| @@ -231,6 +232,7 @@ public class ProjectHelper2 extends ProjectHelper { | |||||
| } | } | ||||
| InputStream inputStream = null; | InputStream inputStream = null; | ||||
| InputSource inputSource = null; | InputSource inputSource = null; | ||||
| ZipFile zf = null; | |||||
| try { | try { | ||||
| /** | /** | ||||
| @@ -243,16 +245,26 @@ public class ProjectHelper2 extends ProjectHelper { | |||||
| uri = FILE_UTILS.toURI(buildFile.getAbsolutePath()); | uri = FILE_UTILS.toURI(buildFile.getAbsolutePath()); | ||||
| inputStream = new FileInputStream(buildFile); | inputStream = new FileInputStream(buildFile); | ||||
| } else { | } 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); | inputSource = new InputSource(inputStream); | ||||
| if (uri != null) { | if (uri != null) { | ||||
| inputSource.setSystemId(uri); | 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; | DefaultHandler hb = handler; | ||||
| @@ -290,6 +302,7 @@ public class ProjectHelper2 extends ProjectHelper { | |||||
| + exc.getMessage(), exc); | + exc.getMessage(), exc); | ||||
| } finally { | } finally { | ||||
| FileUtils.close(inputStream); | 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.IOException; | ||||
| import java.io.InputStream; | import java.io.InputStream; | ||||
| import java.io.OutputStream; | import java.io.OutputStream; | ||||
| import java.net.HttpURLConnection; | |||||
| import java.net.URL; | import java.net.URL; | ||||
| import java.net.URLConnection; | import java.net.URLConnection; | ||||
| import java.net.MalformedURLException; | import java.net.MalformedURLException; | ||||
| import java.net.JarURLConnection; | |||||
| import java.util.jar.JarFile; | |||||
| import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
| import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
| @@ -392,21 +389,10 @@ public class URLResource extends Resource implements URLProvider { | |||||
| * | * | ||||
| */ | */ | ||||
| private synchronized void close() { | 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.UnsupportedEncodingException; | ||||
| import java.io.Writer; | import java.io.Writer; | ||||
| import java.net.MalformedURLException; | import java.net.MalformedURLException; | ||||
| import java.net.HttpURLConnection; | |||||
| import java.net.JarURLConnection; | |||||
| import java.net.URL; | import java.net.URL; | ||||
| import java.net.URLConnection; | |||||
| import java.nio.channels.Channel; | import java.nio.channels.Channel; | ||||
| import java.text.DecimalFormat; | import java.text.DecimalFormat; | ||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||
| @@ -38,6 +41,7 @@ import java.util.Random; | |||||
| import java.util.Stack; | import java.util.Stack; | ||||
| import java.util.StringTokenizer; | import java.util.StringTokenizer; | ||||
| import java.util.Vector; | import java.util.Vector; | ||||
| import java.util.jar.JarFile; | |||||
| import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
| import org.apache.tools.ant.PathTokenizer; | 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. | * Delete the file with {@link File#delete()} if the argument is not null. | ||||
| * Do nothing on a null argument. | * Do nothing on a null argument. | ||||
| @@ -57,4 +57,16 @@ foo=bar | |||||
| <au:assertLogContains text="type is url"/> | <au:assertLogContains text="type is url"/> | ||||
| <au:assertLogContains text="foo is bar"/> | <au:assertLogContains text="foo is bar"/> | ||||
| </target> | </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> | </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> | |||||