git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@830244 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -172,6 +172,31 @@ public abstract class AbstractClasspathResource extends Resource { | |||
| return ((Resource) getCheckedRef()).getInputStream(); | |||
| } | |||
| dieOnCircularReference(); | |||
| final ClassLoaderWithFlag classLoader = getClassLoader(); | |||
| return !classLoader.needsCleanup() | |||
| ? openInputStream(classLoader.getLoader()) | |||
| : new FilterInputStream(openInputStream(classLoader.getLoader())) { | |||
| public void close() throws IOException { | |||
| FileUtils.close(in); | |||
| classLoader.cleanup(); | |||
| } | |||
| protected void finalize() throws Throwable { | |||
| try { | |||
| close(); | |||
| } finally { | |||
| super.finalize(); | |||
| } | |||
| } | |||
| }; | |||
| } | |||
| /** | |||
| * combines the various ways that could specify a ClassLoader and | |||
| * potentially creates one that needs to be cleaned up when it is | |||
| * no longer needed so that classes can get garbage collected. | |||
| */ | |||
| protected ClassLoaderWithFlag getClassLoader() { | |||
| ClassLoader cl = null; | |||
| boolean clNeedsCleanup = false; | |||
| if (loader != null) { | |||
| @@ -196,23 +221,7 @@ public abstract class AbstractClasspathResource extends Resource { | |||
| getProject().addReference(loader.getRefId(), cl); | |||
| } | |||
| } | |||
| final ClassLoader classLoader = cl; | |||
| return !clNeedsCleanup | |||
| ? openInputStream(cl) | |||
| : new FilterInputStream(openInputStream(cl)) { | |||
| public void close() throws IOException { | |||
| FileUtils.close(in); | |||
| ((AntClassLoader) classLoader).cleanup(); | |||
| } | |||
| protected void finalize() throws Throwable { | |||
| try { | |||
| close(); | |||
| } finally { | |||
| super.finalize(); | |||
| } | |||
| } | |||
| }; | |||
| return new ClassLoaderWithFlag(cl, clNeedsCleanup); | |||
| } | |||
| /** | |||
| @@ -237,4 +246,20 @@ public abstract class AbstractClasspathResource extends Resource { | |||
| } | |||
| } | |||
| public static class ClassLoaderWithFlag { | |||
| private final ClassLoader loader; | |||
| private final boolean cleanup; | |||
| ClassLoaderWithFlag(ClassLoader l, boolean needsCleanup) { | |||
| loader = l; | |||
| cleanup = needsCleanup && l instanceof AntClassLoader; | |||
| } | |||
| public ClassLoader getLoader() { return loader; } | |||
| public boolean needsCleanup() { return cleanup; } | |||
| public void cleanup() { | |||
| if (cleanup) { | |||
| ((AntClassLoader) loader).cleanup(); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -20,6 +20,7 @@ package org.apache.tools.ant.types.resources; | |||
| import java.io.FileNotFoundException; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.net.URL; | |||
| import org.apache.tools.ant.types.Path; | |||
| @@ -27,7 +28,8 @@ import org.apache.tools.ant.types.Path; | |||
| * A Resource representation of something loadable via a Java classloader. | |||
| * @since Ant 1.7 | |||
| */ | |||
| public class JavaResource extends AbstractClasspathResource { | |||
| public class JavaResource extends AbstractClasspathResource | |||
| implements URLProvider { | |||
| /** | |||
| * Default constructor. | |||
| @@ -48,8 +50,9 @@ public class JavaResource extends AbstractClasspathResource { | |||
| } | |||
| /** | |||
| * open the inpout stream from a specific classloader | |||
| * @param cl the classloader to use. Will be null if the system classloader is used | |||
| * open the input stream from a specific classloader | |||
| * @param cl the classloader to use. Will be null if the system | |||
| * classloader is used | |||
| * @return an open input stream for the resource | |||
| * @throws IOException if an error occurs. | |||
| */ | |||
| @@ -71,6 +74,27 @@ public class JavaResource extends AbstractClasspathResource { | |||
| return inputStream; | |||
| } | |||
| /** | |||
| * Get the URL represented by this Resource. | |||
| * @since Ant 1.8.0 | |||
| */ | |||
| public URL getURL() { | |||
| if (isReference()) { | |||
| return ((JavaResource) getCheckedRef()).getURL(); | |||
| } | |||
| AbstractClasspathResource.ClassLoaderWithFlag classLoader = | |||
| getClassLoader(); | |||
| if (classLoader.getLoader() == null) { | |||
| return ClassLoader.getSystemResource(getName()); | |||
| } else { | |||
| try { | |||
| return classLoader.getLoader().getResource(getName()); | |||
| } finally { | |||
| classLoader.cleanup(); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * Compare this JavaResource to another Resource. | |||
| * @param another the other Resource against which to compare. | |||
| @@ -38,4 +38,15 @@ public class JavaResourceTest extends BuildFileTest { | |||
| assertTrue(getProject().getProperty("manifest") | |||
| .startsWith("Manifest-Version:")); | |||
| } | |||
| public void testIsURLProvider() { | |||
| JavaResource r = new JavaResource(); | |||
| assertSame(r, r.as(URLProvider.class)); | |||
| } | |||
| public void testGetURLOfManifest() { | |||
| JavaResource r = new JavaResource(); | |||
| r.setName("META-INF/MANIFEST.MF"); | |||
| assertNotNull(r.getURL()); | |||
| } | |||
| } | |||