@SuppressWarnings("unchecked")
private void inferHandlers() {
for (final Map.Entry<WiringElementType, Class<? extends Annotation>> entry : injectionContext.getAllElementMappings()) {
switch (entry.getKey()) {
case TopLevelProvider:
registerHandler(entry.getValue(), new JSR330AnnotationHandler() {
@SuppressWarnings("unchecked")
@Override
public void getDependencies(final DependencyControl control,
final InjectableInstance instance,
final Annotation annotation,
final IOCProcessingContext context) {
final MetaClass providerClassType = instance.getType();
final MetaClass MC_Provider = MetaClassFactory.get(Provider.class);
final MetaClass MC_ContextualTypeProvider = MetaClassFactory.get(ContextualTypeProvider.class);
MetaClass providerInterface = null;
final MetaClass providedType;
if (MC_Provider.isAssignableFrom(providerClassType)) {
for (final MetaClass interfaceType : providerClassType.getInterfaces()) {
if (MC_Provider.equals(interfaceType.getErased())) {
providerInterface = interfaceType;
}
}
if (providerInterface == null) {
throw new RuntimeException("top level provider " + providerClassType.getFullyQualifiedName()
+ " must directly implement " + Provider.class.getName());
}
if (providerInterface.getParameterizedType() == null) {
throw new RuntimeException("top level provider " + providerClassType.getFullyQualifiedName()
+ " must use a parameterized " + Provider.class.getName() + " interface type.");
}
final MetaType parmType = providerInterface.getParameterizedType().getTypeParameters()[0];
if (parmType instanceof MetaParameterizedType) {
providedType = (MetaClass) ((MetaParameterizedType) parmType).getRawType();
}
else {
providedType = (MetaClass) parmType;
}
injectionContext.registerInjector(new ProviderInjector(providedType, providerClassType, injectionContext));
}
else if (MC_ContextualTypeProvider.isAssignableFrom(providerClassType)) {
for (final MetaClass interfaceType : providerClassType.getInterfaces()) {
if (MC_ContextualTypeProvider.equals(interfaceType.getErased())) {
providerInterface = interfaceType;
}
}
if (providerInterface == null) {
throw new RuntimeException("top level provider " + providerClassType.getFullyQualifiedName()
+ " must directly implement " + ContextualTypeProvider.class.getName());
}
if (providerInterface.getParameterizedType() == null) {
throw new RuntimeException("top level provider " + providerClassType.getFullyQualifiedName()
+ " must use a parameterized " + ContextualTypeProvider.class.getName() + " interface type.");
}
final MetaType parmType = providerInterface.getParameterizedType().getTypeParameters()[0];
if (parmType instanceof MetaParameterizedType) {
providedType = (MetaClass) ((MetaParameterizedType) parmType).getRawType();
}
else {
providedType = (MetaClass) parmType;
}
injectionContext.registerInjector(new ContextualProviderInjector(providedType, providerClassType, injectionContext));
}
else {
throw new RuntimeException("top level provider " + providerClassType.getFullyQualifiedName()
+ " does not implement: " + Provider.class.getName() + " or " + ContextualTypeProvider.class);
}
injectionContext.getGraphBuilder().addDependency(providedType, Dependency.on(providerClassType));
control.masqueradeAs(providedType);
super.getDependencies(control, instance, annotation, context);
}
@Override
public boolean handle(final InjectableInstance instance,
final Annotation annotation,
final IOCProcessingContext context) {
return true;
}
}, Rule.before(injectionContext.getAnnotationsForElementType(WiringElementType.SingletonBean),
injectionContext.getAnnotationsForElementType(WiringElementType.DependentBean)));
break;
}
}
for (final Map.Entry<WiringElementType, Class<? extends Annotation>> entry : injectionContext.getAllElementMappings()) {
switch (entry.getKey()) {
case ProducerElement:
registerHandler(entry.getValue(), new JSR330AnnotationHandler() {
@Override
public void getDependencies(final DependencyControl control,
final InjectableInstance instance,
final Annotation annotation,
final IOCProcessingContext context) {
final MetaClass injectedType = instance.getElementTypeOrMethodReturnType();
final MetaClassMember producerMember;
switch (instance.getTaskType()) {
case PrivateMethod:
case Method:
producerMember = instance.getMethod();
for (final MetaParameter parm : instance.getMethod().getParameters()) {
control.notifyDependency(injectedType);
control.notifyDependencies(fillInInterface(parm.getType()));
}
break;
case PrivateField:
case Field:
producerMember = instance.getField();
break;
default:
throw new RuntimeException("illegal producer type");
}
final ProducerInjector producerInjector
= new ProducerInjector(
injectionContext,
injectedType,
producerMember,
instance.getQualifyingMetadata(),
instance);
injectionContext.registerInjector(producerInjector);
control.masqueradeAs(injectedType);
if (!producerMember.isStatic()) {
// if this is a static producer, it does not have a dependency on its parent bean
injectionContext.getGraphBuilder().addDependency(injectedType, Dependency.on(instance.getEnclosingType()));
}
}
@Override
public boolean handle(final InjectableInstance instance,
final Annotation annotation,
final IOCProcessingContext context) {
final List<Injector> injectors = injectionContext.getInjectors(instance.getElementTypeOrMethodReturnType());
for (final Injector injector : injectors) {
if (injector.isEnabled() && injectionContext.isTypeInjectable(injector.getEnclosingType())) {
injector.getBeanInstance(instance);
}
}
return true;
}
}, Rule.after(injectionContext.getAnnotationsForElementType(WiringElementType.SingletonBean),
injectionContext.getAnnotationsForElementType(WiringElementType.DependentBean)));
break;
case DependentBean:
case SingletonBean:
registerHandler(entry.getValue(), new JSR330AnnotationHandler() {
@Override
public boolean handle(final InjectableInstance instance,
final Annotation annotation,
final IOCProcessingContext context) {
final Injector injector = injectionContext.getInjector(instance.getType());