<X> void processAnnotatedType(@Observes ProcessAnnotatedType<X> event, BeanManager beanManager) {
boolean defaultBean = false;
AnnotatedType<X> tp = event.getAnnotatedType();
AnnotatedTypeBuilder<X> builder = null;
Synthetic declaringBeanSyntheticQualifier = null;
Set<Annotation> declaringBeanQualifiers = null;
if (event.getAnnotatedType().isAnnotationPresent(DefaultBean.class)) {
Set<Annotation> qualifiers = new HashSet<Annotation>();
defaultBean = true;
builder = new AnnotatedTypeBuilder<X>().readFromType(tp);
for (Annotation a : tp.getAnnotations()) {
// remove the qualifiers
if (beanManager.isQualifier(a.annotationType())) {
qualifiers.add(a);
builder.removeFromClass(a.annotationType());
}
}
postProcessQualifierSet(qualifiers);
builder.addToClass(new DefaultBeanInformation.Literal(qualifiers));
declaringBeanQualifiers = new HashSet<Annotation>(qualifiers);
declaringBeanSyntheticQualifier = syntheticProvider.get();
// store the qualifiers for later
beanTypeInformation.put(declaringBeanSyntheticQualifier, new DefaultBeanType(qualifiers, tp.getAnnotation(DefaultBean.class).value()));
builder.addToClass(declaringBeanSyntheticQualifier);
}
final Set<Synthetic> producers = new HashSet<Synthetic>();
// now look for producer methods
// if this bean is a default bean then all producers are default beans
// otherwise the annotation needs to be present
for (AnnotatedMethod<? super X> m : tp.getMethods()) {
if (m.isAnnotationPresent(Produces.class) && (defaultBean || m.isAnnotationPresent(DefaultBean.class))) {
if (declaringBeanQualifiers == null) {
declaringBeanQualifiers = new HashSet<Annotation>(Reflections.getQualifiers(beanManager, tp.getAnnotations()));
if (declaringBeanQualifiers.isEmpty()) {
declaringBeanQualifiers.add(DefaultLiteral.INSTANCE);
}
}
if (builder == null) {
builder = new AnnotatedTypeBuilder<X>().readFromType(tp);
}
Set<Annotation> qualifiers = new HashSet<Annotation>();
for (Annotation a : m.getAnnotations()) {
// remove the qualifiers
if (beanManager.isQualifier(a.annotationType())) {
qualifiers.add(a);
builder.removeFromMethod(m, a.annotationType());
}
}
postProcessQualifierSet(qualifiers);
builder.addToMethod(m, new DefaultBeanInformation.Literal(qualifiers));
Synthetic syntheticQualifier = producerSyntheticProvider.get();
// store the qualifiers for later
Type type = null;
// if the type is not explicity set then we infer it
if (m.isAnnotationPresent(DefaultBean.class)) {
type = m.getAnnotation(DefaultBean.class).value();
} else {
type = m.getJavaMember().getGenericReturnType();
}
beanTypeInformation.put(syntheticQualifier, new DefaultBeanType(qualifiers, type));
builder.addToMethod(m, syntheticQualifier);
producerToDeclaringDefaultBean.put(syntheticQualifier, new DefaultBeanQualifiers(declaringBeanSyntheticQualifier, declaringBeanQualifiers));
producers.add(syntheticQualifier);
}
}
//now look for disposer methods
if (!producers.isEmpty()) {
for (AnnotatedMethod<? super X> m : tp.getMethods()) {
for (AnnotatedParameter<? super X> p : m.getParameters()) {
if (p.isAnnotationPresent(Disposes.class)) {
Set<Type> type = p.getTypeClosure();
Set<Annotation> qualifiers = new HashSet<Annotation>();
for (final Annotation annotation : p.getAnnotations()) {
if (beanManager.isQualifier(annotation.annotationType())) {
qualifiers.add(annotation);
}
}
postProcessQualifierSet(qualifiers);
for (final Synthetic producer : producers) {
final DefaultBeanType beanType = beanTypeInformation.get(producer);
Set<Type> types = new HierarchyDiscovery(beanType.getType()).getTypeClosure();
if (Reflections.matches(type, types)) {
if (beanType.getQualifiers().equals(qualifiers)) {
for (final Annotation annotation : p.getAnnotations()) {
if (beanManager.isQualifier(annotation.annotationType())) {
builder.removeFromMethodParameter(m.getJavaMember(), p.getPosition(), annotation.annotationType());
}
}
builder.addToMethodParameter(m.getJavaMember(), p.getPosition(), producer);
}
}
}
}
}
}
}
for (AnnotatedField<? super X> f : tp.getFields()) {
if (f.isAnnotationPresent(Produces.class) && (defaultBean || f.isAnnotationPresent(DefaultBean.class))) {
if (declaringBeanQualifiers == null) {
declaringBeanQualifiers = new HashSet<Annotation>(Reflections.getQualifiers(beanManager, tp.getAnnotations()));
if (declaringBeanQualifiers.isEmpty()) {
declaringBeanQualifiers.add(DefaultLiteral.INSTANCE);
}
}
// we do not support producer fields on normal scoped beans
// as proxies prevent us from reading the fields
for (Annotation i : tp.getAnnotations()) {
if (beanManager.isNormalScope(i.annotationType())) {
deploymentProblems.add(new RuntimeException("Default producer fields are not supported on normal scoped beans. Field: " + f + " Declaring Bean: " + tp));
}
}
if (builder == null) {
builder = new AnnotatedTypeBuilder<X>().readFromType(tp);
}
Set<Annotation> qualifiers = new HashSet<Annotation>();
for (Annotation a : f.getAnnotations()) {
// remove the qualifiers
if (beanManager.isQualifier(a.annotationType())) {
qualifiers.add(a);
builder.removeFromField(f, a.annotationType());
}
}
postProcessQualifierSet(qualifiers);
builder.addToField(f, new DefaultBeanInformation.Literal(qualifiers));
Synthetic syntheticQualifier = producerSyntheticProvider.get();
// store the qualifiers for later
Type type = null;
if (f.isAnnotationPresent(DefaultBean.class)) {
type = f.getAnnotation(DefaultBean.class).value();
} else {