Skip to content

Commit

Permalink
Fixed Enhanced type to match the requested type
Browse files Browse the repository at this point in the history
  • Loading branch information
gastaldi committed Jan 22, 2013
1 parent 8e09662 commit e1beed8
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

/**
* Contains the collection of all installed and available {@link ExportedInstance} types.
*
*
* @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
*/
public interface ServiceRegistry
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,48 +40,51 @@ public <T> void addService(Class<T> clazz)
services.add(clazz);
}

@SuppressWarnings("unchecked")
@Override
public <T> ExportedInstance<T> getExportedInstance(Class<T> clazz)
@SuppressWarnings("unchecked")
public <T> ExportedInstance<T> getExportedInstance(String clazz)
{
ensureAddonStarted();
Class<T> type;
try
{
final Class<T> type;
if (clazz.getClassLoader() == addon.getClassLoader())
{
type = clazz;
}
else
{
type = (Class<T>) Class.forName(clazz.getName(), true, addon.getClassLoader());
}
if (!manager.getBeans(type).isEmpty())
{
return new ExportedInstanceImpl<T>(addon.getClassLoader(), manager, type);
}
type = (Class<T>) loadAddonClass(clazz);
return (ExportedInstance<T>) getExportedInstance(type, type);
}
catch (Exception e)
catch (ClassNotFoundException e)
{
log.log(Level.FINE, "Error while fetching exported instances", e);
return null;
}
return null;
}

@Override
@SuppressWarnings("unchecked")
public <T> ExportedInstance<T> getExportedInstance(String clazz)
public <T> ExportedInstance<T> getExportedInstance(Class<T> clazz)
{
ensureAddonStarted();
return getExportedInstance(clazz, clazz);
}

/**
* @param requestedType interface
* @param actualType Implementation
* @return
*/
private <T> ExportedInstance<T> getExportedInstance(Class<T> requestedType, Class<T> actualType)
{
Class<?> type;
try
{
type = Class.forName(clazz, true, addon.getClassLoader());
return (ExportedInstance<T>) getExportedInstance(type);
final Class<T> requestedLoadedType = loadAddonClass(requestedType);
final Class<? extends T> actualLoadedType = loadAddonClass(actualType);
if (!manager.getBeans(requestedLoadedType).isEmpty())
{
return new ExportedInstanceImpl<T>(addon.getClassLoader(), manager, requestedLoadedType, actualLoadedType);
}
}
catch (ClassNotFoundException e)
catch (Exception e)
{
return null;
log.log(Level.FINE, "Error while fetching exported instances", e);
}
return null;
}

@Override
Expand All @@ -95,7 +98,7 @@ public boolean hasService(String clazz)
{
try
{
Class<?> type = Class.forName(clazz, true, addon.getClassLoader());
Class<?> type = loadAddonClass(clazz);
return hasService(type);
}
catch (ClassNotFoundException e)
Expand All @@ -107,78 +110,110 @@ public boolean hasService(String clazz)
@Override
public boolean hasService(Class<?> clazz)
{
Class<?> type;
try
{
type = loadAddonClass(clazz);
}
catch (ClassNotFoundException e)
{
return false;
}
for (Class<?> service : services)
{
if (clazz.isAssignableFrom(service))
if (type.isAssignableFrom(service))
{
return true;
}
}
return false;
}

@Override
public String toString()
@SuppressWarnings("unchecked")
public <T> Set<ExportedInstance<T>> getExportedInstances(String clazz)
{
return services.toString();
try
{
Class<T> type = (Class<T>) loadAddonClass(clazz);
return getExportedInstances(type);
}
catch (ClassNotFoundException e)
{
return Collections.emptySet();
}
}

@Override
@SuppressWarnings("unchecked")
public <T> Set<ExportedInstance<T>> getExportedInstances(Class<T> clazz)
@Override
public <T> Set<ExportedInstance<T>> getExportedInstances(Class<T> requestedType)
{
ensureAddonStarted();
Set<ExportedInstance<T>> result = new HashSet<ExportedInstance<T>>();
final Class<T> addonLoadedType;
if (clazz.getClassLoader() == addon.getClassLoader())
Class<T> requestedLoadedType;
try
{
addonLoadedType = clazz;
requestedLoadedType = loadAddonClass(requestedType);
}
else
catch (ClassNotFoundException e)
{
try
{
addonLoadedType = (Class<T>) Class.forName(clazz.getName(), true, addon.getClassLoader());
}
catch (Exception e)
{
log.log(Level.FINE, "Error while fetching exported instances", e);
return result;
}
return result;
}

for (Class<?> type : services)
{

if (addonLoadedType.isAssignableFrom(type))
if (requestedLoadedType.isAssignableFrom(type))
{
result.add((ExportedInstance<T>) getExportedInstance(type));
Class<? extends T> assignableClass = (Class<? extends T>) type;
result.add(new ExportedInstanceImpl<T>(addon.getClassLoader(), manager, requestedLoadedType,
assignableClass));
}
}
return result;
}

@Override
public <T> Set<ExportedInstance<T>> getExportedInstances(String clazz)
private void ensureAddonStarted()
{
try
{
@SuppressWarnings("unchecked")
Class<T> type = (Class<T>) Class.forName(clazz, true, addon.getClassLoader());
return getExportedInstances(type);
addon.getFuture().get();
}
catch (ClassNotFoundException e)
catch (Exception e)
{
return Collections.emptySet();
throw new ContainerException("Addon was not started.", e);
}
}

private void ensureAddonStarted()
/**
* Ensures that the returned class is loaded from the addon
*
* @param actualType
* @return
* @throws ClassNotFoundException
*/
@SuppressWarnings("unchecked")
private <T> Class<T> loadAddonClass(Class<T> actualType) throws ClassNotFoundException
{
try
final Class<T> type;
if (actualType.getClassLoader() == addon.getClassLoader())
{
addon.getFuture().get();
type = actualType;
}
catch (Exception e)
else
{
throw new ContainerException("Addon was not started.", e);
type = (Class<T>) loadAddonClass(actualType.getName());
}
return type;
}

private Class<?> loadAddonClass(String className) throws ClassNotFoundException
{
return Class.forName(className, true, addon.getClassLoader());
}

@Override
public String toString()
{
return services.toString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,18 @@ public class ExportedInstanceImpl<R> implements ExportedInstance<R>
{
private ClassLoader loader;
private BeanManager manager;
private Class<R> type;
private CreationalContext<R> context;

public ExportedInstanceImpl(ClassLoader loader, BeanManager manager, Class<R> type)
private Class<R> requestedType;
private Class<? extends R> actualType;

public ExportedInstanceImpl(ClassLoader loader, BeanManager manager, Class<R> requestedType,
Class<? extends R> actualType)
{
this.loader = loader;
this.manager = manager;
this.type = type;
this.requestedType = requestedType;
this.actualType = actualType;
}

@Override
Expand All @@ -39,10 +43,10 @@ public R get()
@Override
public Object call() throws Exception
{
Bean<R> bean = (Bean<R>) manager.resolve(manager.getBeans(type));
Bean<R> bean = (Bean<R>) manager.resolve(manager.getBeans(actualType));
context = manager.createCreationalContext(bean);
Object delegate = manager.getReference(bean, type, context);
return Enhancer.create((Class<?>) type, new RemoteClassLoaderInterceptor(loader, delegate));
Object delegate = manager.getReference(bean, actualType, context);
return Enhancer.create(requestedType, new RemoteClassLoaderInterceptor(loader, delegate));
}
};

Expand All @@ -59,10 +63,10 @@ public Object get(final InjectionPoint injectionPoint)
@Override
public Object call() throws Exception
{
Bean<R> bean = (Bean<R>) manager.resolve(manager.getBeans(type));
Bean<R> bean = (Bean<R>) manager.resolve(manager.getBeans(actualType));
context = manager.createCreationalContext(bean);
Object delegate = manager.getInjectableReference(injectionPoint, context);
return Enhancer.create((Class<?>) type, new RemoteClassLoaderInterceptor(loader, delegate));
return Enhancer.create(requestedType, new RemoteClassLoaderInterceptor(loader, delegate));
}
};

Expand All @@ -78,7 +82,16 @@ public void release(R instance)
@Override
public String toString()
{
return "RemoteInstanceImpl [type=" + type + ", classLoader=" + type.getClassLoader() + "]";
StringBuilder builder = new StringBuilder();
builder.append("ExportedInstanceImpl [");
if (requestedType != null)
builder.append("requestedType=").append(requestedType).append(", ");
if (actualType != null)
builder.append("actualType=").append(actualType).append(", ");
if (loader != null)
builder.append("loader=").append(loader);
builder.append("]");
return builder.toString();
}

private class RemoteClassLoaderInterceptor implements MethodInterceptor
Expand Down

0 comments on commit e1beed8

Please sign in to comment.