Skip to content

Commit

Permalink
Fix bug where service subtypes could not be produced when base type w…
Browse files Browse the repository at this point in the history
…as requested
  • Loading branch information
lincolnthree committed Feb 18, 2014
1 parent ebbc384 commit ae5946e
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

import org.jboss.forge.furnace.Furnace;
import org.jboss.forge.furnace.addons.Addon;
import org.jboss.forge.furnace.container.simple.EventListener;
import org.jboss.forge.furnace.container.simple.Service;
import org.jboss.forge.furnace.exception.ContainerException;
import org.jboss.forge.furnace.spi.ExportedInstance;
import org.jboss.forge.furnace.spi.ServiceRegistry;
Expand All @@ -24,7 +26,6 @@

/**
* @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
*
*/
public class SimpleServiceRegistry implements ServiceRegistry
{
Expand Down Expand Up @@ -62,9 +63,6 @@ public <T> Set<ExportedInstance<T>> getExportedInstances(Class<T> clazz)
{
Addons.waitUntilStarted(addon);

if(clazz.getClassLoader() != addon.getClassLoader())
return Collections.emptySet();

Set<ExportedInstance<T>> result = (Set) instancesCache.get(clazz.getName());

if (result == null)
Expand Down Expand Up @@ -104,9 +102,6 @@ public <T> ExportedInstance<T> getExportedInstance(final Class<T> clazz)
Assert.notNull(clazz, "Requested Class type may not be null");
Addons.waitUntilStarted(addon);

if(clazz.getClassLoader() != addon.getClassLoader())
return null;

ExportedInstance<T> result = (ExportedInstance<T>) instanceCache.get(clazz.getName());
if (result == null)
{
Expand All @@ -125,7 +120,7 @@ public ExportedInstance<T> call() throws Exception
}
}

if (ClassLoaders.ownsClass(addon.getClassLoader(), clazz))
if (ClassLoaders.ownsClass(addon.getClassLoader(), clazz) && isExtensionPointType(clazz))
return new SimpleExportedInstanceImpl<>(furnace, addon, clazz);

return null;
Expand All @@ -146,6 +141,13 @@ public ExportedInstance<T> call() throws Exception
return result;
}

private boolean isExtensionPointType(Class<?> clazz)
{
if (EventListener.class.isAssignableFrom(clazz) || Service.class.isAssignableFrom(clazz))
return true;
return false;
}

@Override
public Set<Class<?>> getExportedTypes()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ public ServiceRegistry getServiceRegistry(Addon addon) throws Exception
if (ClassLoaders.containsClass(addon.getClassLoader(), serviceType))
{
Class<?> type = ClassLoaders.loadClass(addon.getClassLoader(), serviceType);
serviceTypes.add(type);
if (ClassLoaders.ownsClass(addon.getClassLoader(), type))
serviceTypes.add(type);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.jboss.forge.furnace.container.simple;

/**
* @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
*/
public class PublishedServiceSubtype extends PublishedService
{
@Override
public String getMessage()
{
return "I am PublishedServiceSubtype.";
}

@Override
public ClassLoader getClassLoader()
{
return getClass().getClassLoader();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
* @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
*/
@RunWith(Arquillian.class)
public class AddonRegistryIncompatibleServiceLookupTest
public class AddonRegistryIncompatibleServiceLookupTest implements Service
{

@Deployment
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/**
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Eclipse Public License version 1.0, available at
* http://www.eclipse.org/legal/epl-v10.html
*/

package org.jboss.forge.furnace.container.simple;

import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;

import java.util.Iterator;

import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.forge.arquillian.AddonDependency;
import org.jboss.forge.arquillian.Dependencies;
import org.jboss.forge.arquillian.archive.ForgeArchive;
import org.jboss.forge.furnace.addons.Addon;
import org.jboss.forge.furnace.addons.AddonId;
import org.jboss.forge.furnace.addons.AddonRegistry;
import org.jboss.forge.furnace.container.simple.lifecycle.SimpleContainer;
import org.jboss.forge.furnace.repositories.AddonDependencyEntry;
import org.jboss.forge.furnace.services.Imported;
import org.jboss.forge.furnace.spi.ServiceRegistry;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
*
* @author <a href="ggastald@redhat.com">George Gastaldi</a>
*/
@RunWith(Arquillian.class)
public class AddonRegistryInheritanceLookupTest implements Service
{

@Deployment
@Dependencies({
@AddonDependency(name = "org.jboss.forge.furnace.container:simple")
})
public static ForgeArchive getDeployment()
{
ForgeArchive archive = ShrinkWrap.create(ForgeArchive.class)
.addBeansXML()
.addAsAddonDependencies(
AddonDependencyEntry.create("org.jboss.forge.furnace.container:simple"),
AddonDependencyEntry.create("test:dep2"),
AddonDependencyEntry.create("test:dep1")

);

return archive;
}

@Deployment(name = "test:dep2,2", testable = false, order = 2)
public static ForgeArchive getDeploymentDep2()
{
ForgeArchive archive = ShrinkWrap.create(ForgeArchive.class)
.addClass(PublishedServiceSubtype.class)
.addAsServiceProvider(Service.class, PublishedServiceSubtype.class)
.addAsAddonDependencies(
AddonDependencyEntry.create("org.jboss.forge.furnace.container:simple"),
AddonDependencyEntry.create("test:dep1")
);
return archive;
}

@Deployment(name = "test:dep1,1", testable = false, order = 1)
public static ForgeArchive getDeploymentDep1()
{
ForgeArchive archive = ShrinkWrap.create(ForgeArchive.class)
.addClass(PublishedService.class)
.addAsServiceProvider(Service.class, PublishedService.class)
.addAsAddonDependencies(
AddonDependencyEntry.create("org.jboss.forge.furnace.container:simple")
);

return archive;
}

@Test
public void testServiceWithExpectedObjectsDifferentClassLoaders() throws Exception
{
AddonRegistry addonRegistry = SimpleContainer.getFurnace(this.getClass().getClassLoader()).getAddonRegistry();

AddonId depOneId = AddonId.from("test:dep1", "1");
AddonId depTwoId = AddonId.from("test:dep2", "2");

Addon depOne = addonRegistry.getAddon(depOneId);
Addon depTwo = addonRegistry.getAddon(depTwoId);

ServiceRegistry depOneServiceRegistry = depOne.getServiceRegistry();
ServiceRegistry depTwoServiceRegistry = depTwo.getServiceRegistry();

Assert.assertTrue(depOneServiceRegistry.hasService(PublishedService.class));
Assert.assertFalse(depOneServiceRegistry.hasService(PublishedServiceSubtype.class));
Assert.assertTrue(depTwoServiceRegistry.hasService(PublishedService.class));
Assert.assertTrue(depTwoServiceRegistry.hasService(PublishedServiceSubtype.class));

Assert.assertNotNull(depOneServiceRegistry.getExportedInstance(PublishedService.class.getName()));
Assert.assertNotNull(depTwoServiceRegistry.getExportedInstance(PublishedService.class.getName()));
Assert.assertNull(depOneServiceRegistry.getExportedInstance(PublishedServiceSubtype.class.getName()));
Assert.assertNotNull(depTwoServiceRegistry.getExportedInstance(PublishedServiceSubtype.class.getName()));

Imported<PublishedService> services = addonRegistry.getServices(PublishedService.class);
Assert.assertFalse("Imported<PublishedService> should have been satisfied", services.isUnsatisfied());
Assert.assertTrue("Imported<PublishedService> should have been ambiguous", services.isAmbiguous());
Iterator<PublishedService> iterator = services.iterator();
Assert.assertTrue(iterator.hasNext());
Assert.assertThat(iterator.next(), is(instanceOf(PublishedService.class)));
Assert.assertTrue(iterator.hasNext());
Assert.assertThat(iterator.next(), is(instanceOf(PublishedService.class)));

Imported<PublishedServiceSubtype> services2 = addonRegistry.getServices(PublishedServiceSubtype.class);
Assert.assertFalse("Imported<PublishedServiceSubtype> should have been satisfied", services2.isUnsatisfied());
Assert.assertFalse("Imported<PublishedServiceSubtype> should not have been ambiguous", services2.isAmbiguous());
Iterator<PublishedServiceSubtype> iterator2 = services2.iterator();
Assert.assertTrue(iterator2.hasNext());
Assert.assertThat(iterator2.next(), is(instanceOf(PublishedServiceSubtype.class)));
Assert.assertFalse(iterator2.hasNext());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
* @author <a href="ggastald@redhat.com">George Gastaldi</a>
*/
@RunWith(Arquillian.class)
public class AddonRegistryMultipleAddonsTest
public class AddonRegistryMultipleAddonsTest implements Service
{

@Deployment
Expand Down

0 comments on commit ae5946e

Please sign in to comment.