}
public void initializeProviders() {
final MetaClass typeProviderCls = MetaClassFactory.get(TypeProvider.class);
MetaDataScanner scanner = ScannerSingleton.getOrCreateInstance();
/*
* IOCDecoratorExtension.class
*/
Set<Class<?>> iocExtensions = scanner
.getTypesAnnotatedWith(org.jboss.errai.ioc.client.api.IOCExtension.class);
List<IOCExtensionConfigurator> extensionConfigurators = new ArrayList<IOCExtensionConfigurator>();
for (Class<?> clazz : iocExtensions) {
try {
Class<? extends IOCExtensionConfigurator> configuratorClass = clazz.asSubclass(IOCExtensionConfigurator.class);
IOCExtensionConfigurator configurator = configuratorClass.newInstance();
configurator.configure(procContext, injectFactory, procFactory);
extensionConfigurators.add(configurator);
}
catch (Exception e) {
throw new ErraiBootstrapFailure("unable to load IOC Extension Configurator: " + e.getMessage(), e);
}
}
/**
* CodeDecorator.class
*/
Set<Class<?>> decorators = scanner.getTypesAnnotatedWith(CodeDecorator.class);
for (Class<?> clazz : decorators) {
try {
Class<? extends IOCDecoratorExtension> decoratorClass = clazz.asSubclass(IOCDecoratorExtension.class);
Class<? extends Annotation> annoType = null;
Type t = decoratorClass.getGenericSuperclass();
if (!(t instanceof ParameterizedType)) {
throw new ErraiBootstrapFailure("code decorator must extend IOCDecoratorExtension<@AnnotationType>");
}
ParameterizedType pType = (ParameterizedType) t;
if (IOCDecoratorExtension.class.equals(pType.getRawType())) {
if (pType.getActualTypeArguments().length == 0
|| !Annotation.class.isAssignableFrom((Class) pType.getActualTypeArguments()[0])) {
throw new ErraiBootstrapFailure("code decorator must extend IOCDecoratorExtension<@AnnotationType>");
}
//noinspection unchecked
annoType = ((Class) pType.getActualTypeArguments()[0]).asSubclass(Annotation.class);
}
injectFactory.getInjectionContext().registerDecorator(
decoratorClass.getConstructor(new Class[]{Class.class}).newInstance(annoType));
}
catch (Exception e) {
throw new ErraiBootstrapFailure("unable to load code decorator: " + e.getMessage(), e);
}
}
/**
* IOCProvider.class
*/
Set<Class<?>> providers = scanner.getTypesAnnotatedWith(IOCProvider.class);
for (Class<?> clazz : providers) {
MetaClass bindType = null;
MetaClass type = MetaClassFactory.get(clazz);
boolean contextual = false;
for (MetaClass iface : type.getInterfaces()) {
if (iface.getFullyQualifiedName().equals(Provider.class.getName())) {
injectFactory.addType(type);
MetaParameterizedType pType = iface.getParameterizedType();
MetaType typeParm = pType.getTypeParameters()[0];
if (typeParm instanceof MetaParameterizedType) {
bindType = (MetaClass) ((MetaParameterizedType) typeParm).getRawType();
}
else {
bindType = (MetaClass) pType.getTypeParameters()[0];
}
boolean isContextual = false;
for (MetaField field : type.getDeclaredFields()) {
if (field.isAnnotationPresent(Inject.class)
&& field.getType().isAssignableTo(ContextualProviderContext.class)) {
isContextual = true;
break;
}
}
if (isContextual) {
injectFactory.addInjector(new ContextualProviderInjector(bindType, type, procContext));
}
else {
injectFactory.addInjector(new ProviderInjector(bindType, type, procContext));
}
break;
}
if (iface.getFullyQualifiedName().equals(ContextualTypeProvider.class.getName())) {
contextual = true;
MetaParameterizedType pType = iface.getParameterizedType();
if (pType == null) {
throw new InjectionFailure("could not determine the bind type for the IOCProvider class: "
+ type.getFullyQualifiedName());
}
//todo: check for nested type parameters
MetaType typeParm = pType.getTypeParameters()[0];
if (typeParm instanceof MetaParameterizedType) {
bindType = (MetaClass) ((MetaParameterizedType) typeParm).getRawType();
}
else {
bindType = (MetaClass) pType.getTypeParameters()[0];
}
break;
}
}
if (bindType == null) {
for (MetaClass iface : type.getInterfaces()) {
if (!typeProviderCls.isAssignableFrom(iface)) {
continue;
}
MetaParameterizedType pType = iface.getParameterizedType();
if (pType == null) {
throw new InjectionFailure("could not determine the bind type for the IOCProvider class: "
+ type.getFullyQualifiedName());
}
//todo: check for nested type parameters
bindType = (MetaClass) pType.getTypeParameters()[0];
}
}
if (bindType == null) {
throw new InjectionFailure("the annotated provider class does not appear to implement " +
TypeProvider.class.getName() + ": " + type.getFullyQualifiedName());
}
final MetaClass finalBindType = bindType;
Injector injector;
if (contextual) {
injector = new ContextualProviderInjector(finalBindType, type, procContext);
}
else {
injector = new ProviderInjector(finalBindType, type, procContext);
}
injectFactory.addInjector(injector);
}
/**
* GeneratedBy.class
*/
Set<Class<?>> generatedBys = scanner.getTypesAnnotatedWith(GeneratedBy.class);
for (Class<?> clazz : generatedBys) {
MetaClass type = MetaClassFactory.get(typeOracle, clazz);
GeneratedBy anno = type.getAnnotation(GeneratedBy.class);
Class<? extends ContextualTypeProvider> injectorClass = anno.value();