/**
*
* Copyright 2006 The Apache Software Foundation
*
* Licensed 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.geronimo.kernel.classloader;
import java.net.URL;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.jar.Attributes;
import java.io.InputStream;
import java.io.IOException;
import java.io.File;
import java.io.FileOutputStream;
import junit.framework.TestCase;
/**
* @version $Rev: 409817 $ $Date: 2006-05-27 09:56:38 +0200 (Sat, 27 May 2006) $
*/
public class UrlResourceFinderTest extends TestCase {
private File jarFile;
private Manifest manifest;
private Attributes resourceAttributes;
/**
* There are 2 "jars" with a "resource" inside. Make sure the enumeration has exactly 2 elements and
* that hasMoreElements() doesn't advance the iterator.
*
* @throws Exception
*/
public void testResourceEnumeration() throws Exception {
URL jar1 = new File("src/test-data/resourceFinderTest/jar1/").toURL();
URL jar2 = new File("src/test-data/resourceFinderTest/jar2/").toURL();
UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[] {jar1, jar2});
Enumeration enumeration = resourceFinder.findResources("resource");
// resource1
assertTrue(enumeration.hasMoreElements());
assertTrue(enumeration.hasMoreElements());
URL resource1 = (URL) enumeration.nextElement();
assertNotNull(resource1);
assertEquals("resource1", toString(resource1.openStream()));
// resource2
assertTrue(enumeration.hasMoreElements());
assertTrue(enumeration.hasMoreElements());
URL resource2 = (URL) enumeration.nextElement();
assertNotNull(resource2);
assertEquals("resource2", toString(resource2.openStream()));
assertFalse(enumeration.hasMoreElements());
}
public void testDirectoryResource() throws Exception {
URL jar = new File("src/test-data/resourceFinderTest/jar1/").toURL();
UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[] {jar});
ResourceHandle resource = resourceFinder.getResource("resource");
assertNotNull(resource);
// handle.getBytes()
assertEquals("resource1", new String(resource.getBytes()));
// handle.getInputStream()
assertEquals("resource1", toString(resource.getInputStream()));
// handle.getUrl()
URL url = resource.getUrl();
assertEquals("resource1", toString(url.openStream()));
// copy the url and verify we can still get the data
URL copyUrl = new URL(url.toExternalForm());
assertEquals("resource1", toString(copyUrl.openStream()));
// resourceFinder.findResource
URL directUrl = resourceFinder.findResource("resource");
assertEquals("resource1", toString(directUrl.openStream()));
assertEquals("resource1", toString(new URL(directUrl.toExternalForm()).openStream()));
// handle.getContentLength()
assertEquals("resource1".length(), resource.getContentLength());
// handle.getName()
assertEquals("resource", resource.getName());
// handle.getAttributes()
assertNull(resource.getAttributes());
// handle.getManifest()
assertNull(resource.getManifest());
}
public void testJarResource() throws Exception {
URL jar = jarFile.toURL();
UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[] {jar});
ResourceHandle resource = resourceFinder.getResource("resource");
assertNotNull(resource);
// handle.getBytes()
assertEquals("resource3", new String(resource.getBytes()));
// handle.getInputStream()
assertEquals("resource3", toString(resource.getInputStream()));
// handle.getUrl()
URL url = resource.getUrl();
assertEquals("resource3", toString(url.openStream()));
// copy the url and verify we can still get the data
URL copyUrl = new URL(url.toExternalForm());
assertEquals("resource3", toString(copyUrl.openStream()));
// resourceFinder.findResource
URL directUrl = resourceFinder.findResource("resource");
assertEquals("resource3", toString(directUrl.openStream()));
assertEquals("resource3", toString(new URL(directUrl.toExternalForm()).openStream()));
// handle.getContentLength()
assertEquals("resource3".length(), resource.getContentLength());
// handle.getName()
assertEquals("resource", resource.getName());
// handle.getAttributes()
assertEquals(resourceAttributes, resource.getAttributes());
// handle.getManifest()
assertEquals(manifest, resource.getManifest());
}
public void testAddURL() throws Exception {
URL jar1 = new File("src/test-data/resourceFinderTest/jar1/").toURL();
UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[] {jar1});
Enumeration enumeration = resourceFinder.findResources("resource");
// resource1
assertTrue(enumeration.hasMoreElements());
assertTrue(enumeration.hasMoreElements());
URL resource1 = (URL) enumeration.nextElement();
assertNotNull(resource1);
assertEquals("resource1", toString(resource1.openStream()));
assertFalse(enumeration.hasMoreElements());
// addUrl
URL jar2 = new File("src/test-data/resourceFinderTest/jar2/").toURL();
resourceFinder.addUrl(jar2);
// getResource should find the first jar only
ResourceHandle resource = resourceFinder.getResource("resource");
assertNotNull(resource);
assertEquals("resource1", new String(resource.getBytes()));
// findResource should find the first jar only
resource1 = resourceFinder.findResource("resource");
assertEquals("resource1", toString(resource1.openStream()));
// findResouces should see both jars
enumeration = resourceFinder.findResources("resource");
// resource1
assertTrue(enumeration.hasMoreElements());
assertTrue(enumeration.hasMoreElements());
resource1 = (URL) enumeration.nextElement();
assertNotNull(resource1);
assertEquals("resource1", toString(resource1.openStream()));
assertTrue(enumeration.hasMoreElements());
// resource2
assertTrue(enumeration.hasMoreElements());
assertTrue(enumeration.hasMoreElements());
URL resource2 = (URL) enumeration.nextElement();
assertNotNull(resource2);
assertEquals("resource2", toString(resource2.openStream()));
assertFalse(enumeration.hasMoreElements());
}
public void testConcurrentAddURL() throws Exception {
URL jar1 = new File("src/test-data/resourceFinderTest/jar1/").toURL();
URL jar2 = new File("src/test-data/resourceFinderTest/jar2/").toURL();
UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[] {jar1, jar2});
Enumeration enumeration = resourceFinder.findResources("resource");
// resource1
assertTrue(enumeration.hasMoreElements());
assertTrue(enumeration.hasMoreElements());
URL resource1 = (URL) enumeration.nextElement();
assertNotNull(resource1);
assertEquals("resource1", toString(resource1.openStream()));
assertTrue(enumeration.hasMoreElements());
//
// addURL
//
URL newJar = jarFile.toURL();
resourceFinder.addUrl(newJar);
// new resources should be available
// getResource should find the first jar only
ResourceHandle jar3Resouce = resourceFinder.getResource("jar3");
assertNotNull(jar3Resouce);
assertEquals("jar3", new String(jar3Resouce.getBytes()));
// findResource should find the first jar only
URL jar3Url = resourceFinder.findResource("jar3");
assertEquals("jar3", toString(jar3Url.openStream()));
//
// enumeration from above should still be valid, but only see the resources available at the time it was created
//
// resource2
assertTrue(enumeration.hasMoreElements());
assertTrue(enumeration.hasMoreElements());
URL resource2 = (URL) enumeration.nextElement();
assertNotNull(resource2);
assertEquals("resource2", toString(resource2.openStream()));
assertFalse(enumeration.hasMoreElements());
}
public void testDirectoryDestroy() throws Exception {
URL jar = new File("src/test-data/resourceFinderTest/jar1/").toURL();
UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[] {jar});
assertDestroyed(resourceFinder, "resource1", null);
}
public void testJarDestroy() throws Exception {
URL jar = jarFile.toURL();
UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[] {jar});
assertDestroyed(resourceFinder, "resource3", manifest);
}
public void assertDestroyed(UrlResourceFinder resourceFinder, String resourceValue, Manifest expectedManifest) throws Exception {
ResourceHandle resource = resourceFinder.getResource("resource");
assertNotNull(resource);
assertEquals(resourceValue, new String(resource.getBytes()));
// handle.getUrl()
URL url = resource.getUrl();
assertEquals(resourceValue, toString(url.openStream()));
// copy the url and verify we can still get the data
URL copyUrl = new URL(url.toExternalForm());
assertEquals(resourceValue, toString(copyUrl.openStream()));
// resourceFinder.findResource
URL directUrl = resourceFinder.findResource("resource");
assertEquals(resourceValue, toString(directUrl.openStream()));
URL directUrlCopy = new URL(directUrl.toExternalForm());
assertEquals(resourceValue, toString(directUrlCopy.openStream()));
// destroy
resourceFinder.destroy();
// getResource always returns null
assertNull(resourceFinder.getResource("resource"));
// findResource always returns null
assertNull(resourceFinder.findResource("resource"));
// findResources always returns an empty enumeration
assertFalse(resourceFinder.findResources("resource").hasMoreElements());
// existing url may not work
try {
assertEquals(resourceValue, toString(url.openStream()));
} catch (IllegalStateException expected) {
} catch (IOException expected) {
}
try {
assertEquals(resourceValue, toString(directUrl.openStream()));
} catch (IllegalStateException expected) {
} catch (IOException expected) {
}
// the copied urls will work since they are proviced by the vm
assertEquals(resourceValue, toString(copyUrl.openStream()));
assertEquals(resourceValue, toString(directUrlCopy.openStream()));
// existing resource handle may not work since the location was closed
assertEquals("resource", resource.getName());
try {
if (expectedManifest != null) {
assertEquals(expectedManifest.getAttributes("resource"), resource.getAttributes());
}
} catch (IllegalStateException expected) {
}
try {
assertEquals(expectedManifest, resource.getManifest());
} catch (IllegalStateException expected) {
}
try {
assertEquals(resourceValue, toString(resource.getUrl().openStream()));
} catch (IllegalStateException expected) {
}
try {
assertEquals(resourceValue, toString(resource.getInputStream()));
} catch (IllegalStateException expected) {
} catch (IOException expected) {
}
try {
assertEquals(resourceValue, new String(resource.getBytes()));
} catch (IllegalStateException expected) {
} catch (IOException expected) {
}
}
protected void setUp() throws Exception {
super.setUp();
manifest = new Manifest();
Attributes mainAttributes = manifest.getMainAttributes();
mainAttributes.put(Attributes.Name.MANIFEST_VERSION, "1.0");
mainAttributes.putValue("food", "nacho");
resourceAttributes = new Attributes();
resourceAttributes.putValue("drink", "margarita");
manifest.getEntries().put("resource", resourceAttributes);
jarFile = new File("target/resourceFinderTest.jar");
System.out.println(jarFile.getAbsolutePath());
JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream(jarFile), manifest);
jarOutputStream.putNextEntry(new ZipEntry("resource"));
jarOutputStream.write("resource3".getBytes());
jarOutputStream.putNextEntry(new ZipEntry("jar3"));
jarOutputStream.write("jar3".getBytes());
IoUtil.close(jarOutputStream);
}
protected void tearDown() throws Exception {
jarFile.delete();
super.tearDown();
}
private static String toString(InputStream in) throws IOException {
try {
byte[] bytes = IoUtil.getBytes(in);
String string = new String(bytes);
return string;
} finally {
IoUtil.close(in);
}
}
}