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> | |||||