Skip to content

Commit

Permalink
WELD-1144 Superclass of processed AnnotationType is ignored
Browse files Browse the repository at this point in the history
  • Loading branch information
luksa authored and jharting committed Aug 6, 2012
1 parent d008c57 commit b4a7988
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 59 deletions.
Expand Up @@ -250,7 +250,7 @@ protected void initType() {
*/
protected void initInjectableFields() {
injectableFields = Beans.getFieldInjectionPoints(this, annotatedItem);
addInjectionPoints(Beans.getFieldInjectionPoints(this, injectableFields));
addInjectionPoints(Beans.mergeFieldInjectionPoints(injectableFields));
}

/**
Expand Down
Expand Up @@ -167,4 +167,8 @@ public Collection<Annotation> getDeclaredMetaAnnotations(Class<? extends Annotat
public boolean isDiscovered() {
return delegate().isDiscovered();
}

public boolean isModified() {
return delegate().isModified();
}
}
2 changes: 2 additions & 0 deletions impl/src/main/java/org/jboss/weld/introspector/WeldClass.java
Expand Up @@ -184,6 +184,8 @@ public interface WeldClass<T> extends WeldAnnotated<T, Class<T>>, AnnotatedType<

boolean isDiscovered();

boolean isModified();

<S> S cast(Object object);

<U> WeldClass<? extends U> asWeldSubclass(WeldClass<U> clazz);
Expand Down
Expand Up @@ -65,6 +65,7 @@
* @author Pete Muir
* @author David Allen
* @author Ales Justin
* @author Marko Luksa
*/
public class WeldClassImpl<T> extends AbstractWeldAnnotated<T, Class<T>> implements WeldClass<T> {

Expand Down Expand Up @@ -104,6 +105,7 @@ public class WeldClassImpl<T> extends AbstractWeldAnnotated<T, Class<T>> impleme
private final ArraySetMultimap<Class<? extends Annotation>, Annotation> declaredMetaAnnotationMap;

private final boolean discovered;
private final boolean modified;

public static <T> WeldClass<T> of(Class<T> clazz, ClassTransformer classTransformer) {
return new WeldClassImpl<T>(clazz, clazz, null, new TypeClosureLazyValueHolder(clazz), buildAnnotationMap(clazz.getAnnotations()), buildAnnotationMap(clazz.getDeclaredAnnotations()), classTransformer);
Expand All @@ -120,7 +122,6 @@ public static <T> WeldClass<T> of(Class<T> rawType, Type type, ClassTransformer
protected WeldClassImpl(Class<T> rawType, Type type, AnnotatedType<T> annotatedType, LazyValueHolder<Set<Type>> typeClosure, Map<Class<? extends Annotation>, Annotation> annotationMap, Map<Class<? extends Annotation>, Annotation> declaredAnnotationMap, ClassTransformer classTransformer) {
super(annotationMap, declaredAnnotationMap, classTransformer, rawType, type, typeClosure);

boolean modified;
if (annotatedType instanceof DiscoveredExternalAnnotatedType) {
discovered = true;
modified = DiscoveredExternalAnnotatedType.class.cast(annotatedType).isModifed();
Expand Down Expand Up @@ -623,4 +624,7 @@ public boolean isDiscovered() {
return discovered;
}

public boolean isModified() {
return modified;
}
}
Expand Up @@ -75,7 +75,7 @@ public SimpleInjectionTarget(WeldClass<T> type, BeanManagerImpl beanManager) {
}
this.constructor = constructor;
this.injectableFields = Beans.getFieldInjectionPoints(null, type);
this.injectionPoints.addAll(Beans.getFieldInjectionPoints(null, this.injectableFields));
this.injectionPoints.addAll(Beans.mergeFieldInjectionPoints(this.injectableFields));
this.initializerMethods = Beans.getInitializerMethods(null, type);
this.injectionPoints.addAll(Beans.getParameterInjectionPoints(null, initializerMethods));
this.postConstructMethods = Beans.getPostConstructMethods(type);
Expand Down
167 changes: 121 additions & 46 deletions impl/src/main/java/org/jboss/weld/util/Beans.java
Expand Up @@ -79,6 +79,7 @@
import org.jboss.weld.persistence.PersistenceApiAbstraction;
import org.jboss.weld.resolution.QualifierInstance;
import org.jboss.weld.util.collections.ArraySet;
import org.jboss.weld.util.collections.HashSetSupplier;
import org.jboss.weld.util.reflection.Reflections;
import org.slf4j.cal10n.LocLogger;

Expand Down Expand Up @@ -187,30 +188,68 @@ public static boolean isBeanProxyable(Bean<?> bean) {
}

public static List<Set<FieldInjectionPoint<?, ?>>> getFieldInjectionPoints(Bean<?> declaringBean, WeldClass<?> weldClass) {
if (weldClass.isModified()) {
return getFieldInjectionPointsFromWeldFields(declaringBean, weldClass);
} else {
return getFieldInjectionPointsFromDeclaredFields(declaringBean, weldClass);
}
}

private static List<Set<FieldInjectionPoint<?, ?>>> getFieldInjectionPointsFromWeldFields(Bean<?> declaringBean, WeldClass<?> weldClass) {
Collection<WeldField<?, ?>> allFields = weldClass.getWeldFields(Inject.class);

List<Set<FieldInjectionPoint<?, ?>>> injectableFields = new ArrayList<Set<FieldInjectionPoint<?, ?>>>();
Class<?> clazz = weldClass.getJavaClass();
while (clazz != null) {
ArraySet<FieldInjectionPoint<?, ?>> set = new ArraySet<FieldInjectionPoint<?, ?>>();
for (WeldField<?, ?> field : allFields) {
Class<?> declaringClass = field.getJavaMember().getDeclaringClass();
if (declaringClass.equals(clazz)) {
addFieldInjectionPoint(declaringBean, weldClass, field, set);
}
}
set.trimToSize();
injectableFields.add(0, set);

clazz = clazz.getSuperclass();
}
return injectableFields;
}

private static List<Set<FieldInjectionPoint<?, ?>>> getFieldInjectionPointsFromDeclaredFields(Bean<?> declaringBean, WeldClass<?> weldClass) {
List<Set<FieldInjectionPoint<?, ?>>> list = new ArrayList<Set<FieldInjectionPoint<?, ?>>>();
WeldClass<?> c = weldClass;
while (c != null && !c.getJavaClass().equals(Object.class)) {
list.add(0, getDeclaredFieldInjectionPoints(declaringBean, weldClass, c));
ArraySet<FieldInjectionPoint<?, ?>> injectionPoints = new ArraySet<FieldInjectionPoint<?, ?>>();
for (WeldField<?, ?> field : c.getDeclaredWeldFields(Inject.class)) {
addFieldInjectionPoint(declaringBean, weldClass, field, injectionPoints);
}
injectionPoints.trimToSize();
list.add(0, injectionPoints);

c = c.getWeldSuperclass();
}
return list;
}

private static Set<FieldInjectionPoint<?, ?>> getDeclaredFieldInjectionPoints(Bean<?> declaringBean, WeldClass<?> injectionTargetClass, WeldClass<?> fieldDeclaringClass) {
ArraySet<FieldInjectionPoint<?, ?>> fields = new ArraySet<FieldInjectionPoint<?, ?>>();
for (WeldField<?, ?> field : fieldDeclaringClass.getDeclaredWeldFields(Inject.class)) {
if (!field.isStatic() && !field.isAnnotationPresent(Produces.class)) {
if (field.isFinal()) {
throw new DefinitionException(QUALIFIER_ON_FINAL_FIELD, field);
}
fields.add(FieldInjectionPoint.of(declaringBean, injectionTargetClass, field));
}
private static void addFieldInjectionPoint(Bean<?> declaringBean, WeldClass<?> weldClass, WeldField<?, ?> field, Set<FieldInjectionPoint<?, ?>> injectionPoints) {
if (isInjectableField(field)) {
validateInjectableField(field);
injectionPoints.add(FieldInjectionPoint.of(declaringBean, weldClass, field));
}
}

private static boolean isInjectableField(WeldField<?, ?> field) {
return !field.isStatic() && !field.isAnnotationPresent(Produces.class);
}

private static void validateInjectableField(WeldField<?, ?> field) {
if (field.isFinal()) {
throw new DefinitionException(QUALIFIER_ON_FINAL_FIELD, field);
}
fields.trimToSize();
return fields;
}

public static Set<FieldInjectionPoint<?, ?>> getFieldInjectionPoints(Bean<?> declaringBean, List<? extends Set<? extends FieldInjectionPoint<?, ?>>> fieldInjectionPoints) {
public static Set<FieldInjectionPoint<?, ?>> mergeFieldInjectionPoints(List<? extends Set<? extends FieldInjectionPoint<?, ?>>> fieldInjectionPoints) {
ArraySet<FieldInjectionPoint<?, ?>> injectionPoints = new ArraySet<FieldInjectionPoint<?, ?>>();
for (Set<? extends FieldInjectionPoint<?, ?>> i : fieldInjectionPoints) {
injectionPoints.addAll(i);
Expand Down Expand Up @@ -341,43 +380,79 @@ public Set<Package> get() {
return set.trimToSize();
}

public static List<Set<MethodInjectionPoint<?, ?>>> getInitializerMethods(Bean<?> declaringBean, WeldClass<?> type) {
List<Set<MethodInjectionPoint<?, ?>>> initializerMethodsList = new ArrayList<Set<MethodInjectionPoint<?, ?>>>();
public static List<Set<MethodInjectionPoint<?, ?>>> getInitializerMethods(Bean<?> declaringBean, WeldClass<?> weldClass) {
if (weldClass.isModified()) {
return getInitializerMethodsFromWeldMethods(declaringBean, weldClass);
} else {
return getInitializerMethodsFromDeclaredMethods(declaringBean, weldClass);
}
}

private static <T> List<Set<MethodInjectionPoint<?, ?>>> getInitializerMethodsFromWeldMethods(Bean<?> declaringBean, WeldClass<T> weldClass) {
List<Set<MethodInjectionPoint<?, ?>>> initializerMethods = new ArrayList<Set<MethodInjectionPoint<?, ?>>>();

// Keep track of all seen methods so we can ignore overridden methods
Multimap<MethodSignature, Package> seenMethods = Multimaps.newSetMultimap(new HashMap<MethodSignature, Collection<Package>>(), new Supplier<Set<Package>>() {
Multimap<MethodSignature, Package> seenMethods = Multimaps.newSetMultimap(new HashMap<MethodSignature, Collection<Package>>(), HashSetSupplier.<Package>instance());

Class<?> clazz = weldClass.getJavaClass();
while (clazz != null) {
ArraySet<MethodInjectionPoint<?, ?>> set = new ArraySet<MethodInjectionPoint<?, ?>>();
for (WeldMethod<?, ?> weldMethod : weldClass.getWeldMethods()) {
if (weldMethod.getJavaMember().getDeclaringClass().equals(clazz)) {
processPossibleInitializerMethod(declaringBean, weldClass, weldMethod, seenMethods, set);
}
}
set.trimToSize();
initializerMethods.add(0, set);

public Set<Package> get() {
return new HashSet<Package>();
clazz = clazz.getSuperclass();
}

return initializerMethods;
}

public static List<Set<MethodInjectionPoint<?, ?>>> getInitializerMethodsFromDeclaredMethods(Bean<?> declaringBean, WeldClass<?> weldClass) {
List<Set<MethodInjectionPoint<?, ?>>> list = new ArrayList<Set<MethodInjectionPoint<?, ?>>>();
// Keep track of all seen methods so we can ignore overridden methods
Multimap<MethodSignature, Package> seenMethods = Multimaps.newSetMultimap(new HashMap<MethodSignature, Collection<Package>>(), HashSetSupplier.<Package>instance());
WeldClass<?> clazz = weldClass;
while (clazz != null && !clazz.getJavaClass().equals(Object.class)) {
ArraySet<MethodInjectionPoint<?, ?>> set = new ArraySet<MethodInjectionPoint<?, ?>>();
Collection declaredWeldMethods = clazz.getDeclaredWeldMethods();
for (WeldMethod<?, ?> method : (Collection<WeldMethod<?, ?>>) declaredWeldMethods) {
processPossibleInitializerMethod(declaringBean, weldClass, method, seenMethods, set);
}
set.trimToSize();
list.add(0, set);
clazz = clazz.getWeldSuperclass();
}
return list;
}

});
WeldClass<?> t = type;
while (t != null && !t.getJavaClass().equals(Object.class)) {
ArraySet<MethodInjectionPoint<?, ?>> initializerMethods = new ArraySet<MethodInjectionPoint<?, ?>>();
initializerMethodsList.add(0, initializerMethods);
for (WeldMethod<?, ?> method : t.getDeclaredWeldMethods()) {
if (method.isAnnotationPresent(Inject.class) && !method.isStatic()) {
if (method.getAnnotation(Produces.class) != null) {
throw new DefinitionException(INITIALIZER_CANNOT_BE_PRODUCER, method, type);
} else if (method.getWeldParameters(Disposes.class).size() > 0) {
throw new DefinitionException(INITIALIZER_CANNOT_BE_DISPOSAL_METHOD, method, type);
} else if (method.getWeldParameters(Observes.class).size() > 0) {
throw new DefinitionException(INVALID_INITIALIZER, method);
} else if (method.isGeneric()) {
throw new DefinitionException(INITIALIZER_METHOD_IS_GENERIC, method, type);
} else {
if (!isOverridden(method, seenMethods)) {
MethodInjectionPoint<?, ?> initializerMethod = MethodInjectionPoint.of(declaringBean, method);
initializerMethods.add(initializerMethod);
}
}
}
seenMethods.put(method.getSignature(), method.getPackage());
private static void processPossibleInitializerMethod(Bean<?> declaringBean, WeldClass<?> injectionTargetClass, WeldMethod<?, ?> method, Multimap<MethodSignature, Package> seenMethods, ArraySet<MethodInjectionPoint<?, ?>> set) {
if (isInitializerMethod(method)) {
validateInitializerMethod(method, injectionTargetClass);
if (!isOverridden(method, seenMethods)) {
set.add(MethodInjectionPoint.of(declaringBean, method));
}
initializerMethods.trimToSize();
t = t.getWeldSuperclass();
}
return initializerMethodsList;
seenMethods.put(method.getSignature(), method.getPackage());
}

private static boolean isInitializerMethod(WeldMethod<?, ?> method) {
return method.isAnnotationPresent(Inject.class) && !method.isStatic();
}

private static void validateInitializerMethod(WeldMethod<?, ?> method, WeldClass<?> type) {
if (method.getAnnotation(Produces.class) != null) {
throw new DefinitionException(INITIALIZER_CANNOT_BE_PRODUCER, method, type);
} else if (method.getWeldParameters(Disposes.class).size() > 0) {
throw new DefinitionException(INITIALIZER_CANNOT_BE_DISPOSAL_METHOD, method, type);
} else if (method.getWeldParameters(Observes.class).size() > 0) {
throw new DefinitionException(INVALID_INITIALIZER, method);
} else if (method.isGeneric()) {
throw new DefinitionException(INITIALIZER_METHOD_IS_GENERIC, method, type);
}
}

private static boolean isOverridden(WeldMethod<?, ?> method, Multimap<MethodSignature, Package> seenMethods) {
Expand Down Expand Up @@ -457,7 +532,7 @@ public static boolean findInterceptorBindingConflicts(Set<InterceptorBindingType
* <p/>
* The deployment type X is
*
* @param beans The beans to filter
* @param beans The beans to filter
* @param beanManager the bean manager
* @return The filtered beans
*/
Expand Down Expand Up @@ -487,7 +562,7 @@ public static boolean isBeanEnabled(Bean<?> bean, Enabled enabled) {
}
return false;
}
} else if (bean instanceof AbstractReceiverBean<?,?,?>) {
} else if (bean instanceof AbstractReceiverBean<?, ?, ?>) {
AbstractReceiverBean<?, ?, ?> receiverBean = (AbstractReceiverBean<?, ?, ?>) bean;
return isBeanEnabled(receiverBean.getDeclaringBean(), enabled);
} else if (bean instanceof DecoratorImpl<?>) {
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Expand Up @@ -551,7 +551,7 @@
</executions>
</plugin>

<!-- So m2e doesn't throw errors for features it doesn't support in the
<!-- So m2e doesn't throw errors for features it doesn't support in the
POM -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
Expand Down
Expand Up @@ -6,7 +6,6 @@
/**
* Session Bean implementation class CdiTest
*/
@Stateless
public class CdiTest1 {

@Inject
Expand Down
Expand Up @@ -3,7 +3,6 @@
import javax.ejb.Stateless;
import javax.inject.Inject;

@Stateless
public class CdiTest2 extends CdiTest1 {

@Inject
Expand Down
Expand Up @@ -2,7 +2,6 @@

import javax.ejb.Stateless;

@Stateless
public class SomeInjectedBean {

}
Expand Up @@ -33,21 +33,15 @@ public static Archive getDeployment() {
private Instance<CdiTest2> test;

@Test
@Ignore
public void testChildClassFieldIsInjected() {
CdiTest2 cdiTest2 = test.get();
assertNotNull(cdiTest2.getSomeInjectedBean2());
}

@Test
@Ignore
public void testSuperclassFieldIsInjected() {
CdiTest2 cdiTest2 = test.get();
assertNotNull(cdiTest2.getSomeInjectedBean1());
}

@Test
public void testDummy() {
// remove it
}
}

0 comments on commit b4a7988

Please sign in to comment.