configurator.configure(procContext, injectFactory, procFactory);
extensionConfigurators.add(configurator);
}
catch (Exception e) {
throw new ErraiBootstrapFailure("unable to load IOC Extension Configurator: " + e.getMessage(), e);
}
}
Set<Class<?>> bootstrappers = scanner.getTypesAnnotatedWith(IOCBootstrapTask.class);
for (Class<?> clazz : bootstrappers) {
IOCBootstrapTask task = clazz.getAnnotation(IOCBootstrapTask.class);
if (task.value() == TaskOrder.Before) {
beforeTasks.add(clazz);
}
else {
afterTasks.add(clazz);
}
}
/**
* 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 = GWTClass.newInstance(typeOracle, clazz.getName());
GeneratedBy anno = type.getAnnotation(GeneratedBy.class);
Class<? extends ContextualTypeProvider> injectorClass = anno.value();
try {
injectFactory
.addInjector(new ContextualProviderInjector(type, MetaClassFactory.get(injectorClass), procContext));
}
catch (Exception e) {
throw new ErraiBootstrapFailure("could not load injector: " + e.getMessage(), e);
}
}
for (IOCExtensionConfigurator extensionConfigurator : extensionConfigurators) {
extensionConfigurator.afterInitialization(procContext, injectFactory, procFactory);