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