Skip to content

Commit

Permalink
Resolves FORGE-876 - Cannot inject services with wildcard types.
Browse files Browse the repository at this point in the history
  • Loading branch information
lincolnthree committed Aug 28, 2013
1 parent 398ace3 commit c78e35f
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
Expand Down Expand Up @@ -129,12 +131,17 @@ public void wireCrossContainerServices(@Observes AfterBeanDiscovery event, final
final Annotated annotated = injectionPoint.getAnnotated();
final Member member = injectionPoint.getMember();

Set<Type> typeClosure = annotated.getTypeClosure();
Class<?> beanClass = entry.getValue();
Set<Type> typeClosure = annotated.getTypeClosure();
Set<Type> beanTypeClosure = new LinkedHashSet<Type>();
for (Type type : typeClosure)
{
beanTypeClosure.add(reifyWildcardsToObjects(type));
}

Bean<?> serviceBean = new BeanBuilder<Object>(manager)
.beanClass(beanClass)
.types(typeClosure)
.types(beanTypeClosure)
.beanLifecycle(new ContextualLifecycle<Object>()
{
@Override
Expand Down Expand Up @@ -189,6 +196,68 @@ else if (member instanceof Constructor)
}
}

private Type reifyWildcardsToObjects(final Type type)
{
if (type instanceof ParameterizedType)
{
final Type[] arguments = ((ParameterizedType) type).getActualTypeArguments();
if (arguments != null)
{
boolean modified = false;
final Type[] reifiedArguments = new Type[arguments.length];
for (int i = 0; i < arguments.length; i++)
{
final Type argument = arguments[i];
Type reified = argument;
if (argument instanceof WildcardType)
{
if (((WildcardType) argument).getLowerBounds().length == 0)
{
Type[] upperBounds = ((WildcardType) argument).getUpperBounds();
if (upperBounds.length == 1 && upperBounds[0].equals(Object.class))
reified = Object.class;
}

}
else
{
reified = reifyWildcardsToObjects(argument);
}

reifiedArguments[i] = reified;

if (reified != argument)
modified = true;
}

if (modified)
{
return new ParameterizedType()
{
@Override
public Type getRawType()
{
return ((ParameterizedType) type).getRawType();
}

@Override
public Type getOwnerType()
{
return ((ParameterizedType) type).getOwnerType();
}

@Override
public Type[] getActualTypeArguments()
{
return reifiedArguments;
}
};
}
}
}
return type;
}

/*
* Helpers
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,17 @@ public <T> Set<ExportedInstance<T>> getExportedInstances(Class<T> requestedType)
{
Set<Bean<?>> beans = manager.getBeans(type, getQualifiersFrom(type));
Class<? extends T> assignableClass = (Class<? extends T>) type;
result.add(new ExportedInstanceImpl<T>(addon,
manager, (Bean<T>) manager.resolve(beans),
requestedLoadedType,
assignableClass
));
for (Bean<?> bean : beans)
{
result.add(new ExportedInstanceImpl<T>(
addon,
manager,
(Bean<T>) bean,
requestedLoadedType,
assignableClass
));

}
}
}
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.jboss.forge.furnace.proxy.ClassLoaderInterceptor;
import org.jboss.forge.furnace.proxy.Proxies;
import org.jboss.forge.furnace.spi.ExportedInstance;
import org.jboss.forge.furnace.util.Assert;
import org.jboss.forge.furnace.util.ClassLoaders;

public class ExportedInstanceImpl<R> implements ExportedInstance<R>
Expand All @@ -35,6 +36,11 @@ public class ExportedInstanceImpl<R> implements ExportedInstance<R>
public ExportedInstanceImpl(Addon addon, BeanManager manager, Bean<R> requestedBean, Class<R> requestedType,
Class<? extends R> actualType)
{
Assert.notNull(addon, "Source addon must not be null.");
Assert.notNull(manager, "Bean manager must not be null.");
Assert.notNull(requestedBean, "Requested bean must not be null.");
Assert.notNull(requestedType, "Requested type must not be null.");
Assert.notNull(actualType, "Actual type must not be null.");
this.addon = addon;
this.manager = manager;
this.requestedBean = requestedBean;
Expand Down

0 comments on commit c78e35f

Please sign in to comment.