blob: 13237429e78d4bc6fc6f826084c16e7a8cb14ab3 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010-present Sonatype, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Stuart McCulloch (Sonatype, Inc.) - initial API and implementation
*******************************************************************************/
package org.eclipse.sisu.space;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.jar.Manifest;
import org.apache.felix.framework.FrameworkFactory;
import org.eclipse.sisu.inject.DeferredClass;
import org.junit.Ignore;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
import org.osgi.framework.launch.Framework;
import junit.framework.TestCase;
@Ignore( "Need to replace some test archives" )
public class BundleClassSpaceTest
extends TestCase
{
private static final URL EMPTY_BUNDLE = ZipEntryIteratorTest.class.getResource( "empty.jar" );
private static final URL SIMPLE_BUNDLE = ZipEntryIteratorTest.class.getResource( "simple_bundle.jar" );
private static final URL LOGGING_BUNDLE = ZipEntryIteratorTest.class.getResource( "logging_bundle.jar" );
private Framework framework;
@Override
protected void setUp()
throws Exception
{
super.setUp();
final Map<String, String> configuration = new HashMap<String, String>();
configuration.put( Constants.FRAMEWORK_STORAGE_CLEAN, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT );
configuration.put( Constants.FRAMEWORK_STORAGE, "target/bundlecache" );
final FrameworkFactory frameworkFactory = new FrameworkFactory();
framework = frameworkFactory.newFramework( configuration );
framework.start();
}
@Override
protected void tearDown()
throws Exception
{
framework.stop();
framework.waitForStop( 0 );
super.tearDown();
}
public void testHashCodeAndEquals()
throws Exception
{
final Bundle testBundle = framework.getBundleContext().installBundle( LOGGING_BUNDLE.toString() );
final ClassSpace space = new BundleClassSpace( testBundle );
assertEquals( space, space );
assertEquals( space, new BundleClassSpace( testBundle ) );
assertFalse( space.equals( new ClassSpace()
{
public Class<?> loadClass( final String name )
{
return space.loadClass( name );
}
public DeferredClass<?> deferLoadClass( final String name )
{
return space.deferLoadClass( name );
}
public Enumeration<URL> getResources( final String name )
{
return space.getResources( name );
}
public URL getResource( final String name )
{
return space.getResource( name );
}
public Enumeration<URL> findEntries( final String path, final String glob, final boolean recurse )
{
return space.findEntries( path, glob, recurse );
}
} ) );
assertEquals( testBundle.hashCode(), space.hashCode() );
assertEquals( testBundle.toString(), space.toString() );
}
public void testClassSpaceResources()
throws Exception
{
final Bundle testBundle1 = framework.getBundleContext().installBundle( LOGGING_BUNDLE.toString() );
final ClassSpace space1 = new BundleClassSpace( testBundle1 );
final Bundle testBundle2 = framework.getBundleContext().installBundle( SIMPLE_BUNDLE.toString() );
final ClassSpace space2 = new BundleClassSpace( testBundle2 );
final Bundle testBundle3 = framework.getBundleContext().installBundle( EMPTY_BUNDLE.toString() );
final ClassSpace space3 = new BundleClassSpace( testBundle3 );
Enumeration<URL> e;
// logging bundle class-path has repeated entries...
e = space1.getResources( "META-INF/MANIFEST.MF" );
assertTrue( e.hasMoreElements() );
assertTrue( e.nextElement().toString().matches( "bundle://.*/META-INF/MANIFEST.MF" ) );
assertTrue( e.nextElement().toString().matches( "bundle://.*/META-INF/MANIFEST.MF" ) );
assertTrue( e.nextElement().toString().matches( "bundle://.*/META-INF/MANIFEST.MF" ) );
assertTrue( e.nextElement().toString().matches( "bundle://.*/META-INF/MANIFEST.MF" ) );
assertFalse( e.hasMoreElements() );
// ...which we try to collapse when using find
e = space1.findEntries( "META-INF", "*.MF", false );
assertTrue( e.hasMoreElements() );
assertTrue( e.nextElement().toString().matches( "bundle://.*/META-INF/MANIFEST.MF" ) );
assertTrue( e.nextElement().toString().matches( "jar:bundle://.*!/META-INF/MANIFEST.MF" ) );
assertFalse( e.hasMoreElements() );
try
{
e.nextElement();
fail( "Expected NoSuchElementException" );
}
catch ( final NoSuchElementException t )
{
}
e = space2.findEntries( "a/b", "*", true );
assertTrue( e.hasMoreElements() );
assertTrue( e.nextElement().toString().matches( "bundle://.*/a/b/2" ) );
assertTrue( e.nextElement().toString().matches( "bundle://.*/a/b/c/" ) );
assertTrue( e.nextElement().toString().matches( "bundle://.*/a/b/c/3" ) );
assertFalse( e.hasMoreElements() );
e = space3.findEntries( "", "*", true );
assertTrue( e.nextElement().toString().matches( "bundle://.*/META-INF/" ) );
assertTrue( e.nextElement().toString().matches( "bundle://.*/META-INF/MANIFEST.MF" ) );
assertFalse( e.hasMoreElements() );
e = space1.findEntries( null, "missing", true );
assertFalse( e.hasMoreElements() );
e = space2.findEntries( null, "missing", true );
assertFalse( e.hasMoreElements() );
e = space3.findEntries( null, "missing", true );
assertFalse( e.hasMoreElements() );
final URL manifestURL = space1.getResource( "META-INF/MANIFEST.MF" );
assertNotNull( manifestURL );
new Manifest( manifestURL.openStream() );
}
public void testDeferredClass()
throws Exception
{
final Bundle testBundle = framework.getBundleContext().installBundle( LOGGING_BUNDLE.toString() );
final ClassSpace space = new BundleClassSpace( testBundle );
final String clazzName = "org.apache.commons.logging.Log";
final DeferredClass<?> clazz = space.deferLoadClass( clazzName );
assertEquals( clazzName, clazz.getName() );
assertSame( space.loadClass( clazzName ), clazz.load() );
final DeferredClass<?> missingClazz = space.deferLoadClass( "missing.class" );
try
{
missingClazz.load();
fail( "Expected TypeNotPresentException" );
}
catch ( final TypeNotPresentException e )
{
}
}
public void testBrokenResources()
{
final InvocationHandler handler = new InvocationHandler()
{
public Object invoke( final Object proxy, final Method method, final Object[] args )
throws Throwable
{
throw new IOException();
}
};
final ClassSpace space =
new BundleClassSpace( (Bundle) Proxy.newProxyInstance( Bundle.class.getClassLoader(),
new Class<?>[] { Bundle.class }, handler ) );
assertFalse( space.getResources( "error" ).hasMoreElements() );
}
}