Skip to content

Commit

Permalink
Merge pull request quarkusio#28064 from mkouba/fix-qualifier-registra…
Browse files Browse the repository at this point in the history
…tion-next

ArC - verify _registered_ qualifiers
  • Loading branch information
mkouba authored Sep 20, 2022
2 parents cfc4b66 + d7e75eb commit 5a1eef0
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public class BeanDeployment {
nonbindingMembers = Collections.emptySet();
}
qualifierNonbindingMembers.put(dotName, nonbindingMembers);
this.qualifiers.put(dotName, classInfo);
qualifiers.put(dotName, classInfo);
}
}
}
Expand Down Expand Up @@ -558,7 +558,7 @@ ClassInfo getQualifier(DotName name) {
}

boolean isInheritedQualifier(DotName name) {
return (getQualifier(name).classAnnotation(DotNames.INHERITED) != null);
return (getQualifier(name).declaredAnnotation(DotNames.INHERITED) != null);
}

/**
Expand Down Expand Up @@ -682,7 +682,7 @@ private Map<DotName, ClassInfo> findQualifiers(IndexView index) {
private Map<DotName, ClassInfo> findContainerAnnotations(Map<DotName, ClassInfo> annotations, IndexView index) {
Map<DotName, ClassInfo> containerAnnotations = new HashMap<>();
for (ClassInfo annotation : annotations.values()) {
AnnotationInstance repeatableMetaAnnotation = annotation.classAnnotation(DotNames.REPEATABLE);
AnnotationInstance repeatableMetaAnnotation = annotation.declaredAnnotation(DotNames.REPEATABLE);
if (repeatableMetaAnnotation != null) {
DotName containerAnnotationName = repeatableMetaAnnotation.value().asClass().name();
ClassInfo containerClass = getClassByName(index, containerAnnotationName);
Expand Down Expand Up @@ -799,7 +799,7 @@ private Map<DotName, StereotypeInfo> findStereotypes(IndexView index, Map<DotNam
}
boolean isAdditionalStereotype = additionalStereotypes.contains(stereotypeName);
final ScopeInfo scope = getValidScope(scopes, stereotypeClass);
boolean isInherited = stereotypeClass.classAnnotation(DotNames.INHERITED) != null;
boolean isInherited = stereotypeClass.declaredAnnotation(DotNames.INHERITED) != null;
stereotypes.put(stereotypeName, new StereotypeInfo(scope, bindings, isAlternative, alternativePriority,
isNamed, isAdditionalStereotype, stereotypeClass, isInherited, parentStereotypes));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@ Collection<Resource> generate(String name, BeanDeployment beanDeployment, Map<Be
classOutput);
}

// All qualifiers
ResultHandle qualifiers = getComponents.newInstance(MethodDescriptor.ofConstructor(HashSet.class));
for (ClassInfo qualifier : beanDeployment.getQualifiers()) {
getComponents.invokeInterfaceMethod(MethodDescriptors.SET_ADD, qualifiers,
getComponents.load(qualifier.name().toString()));
}

// Qualifier non-binding members
ResultHandle qualifiersNonbindingMembers = getComponents.newInstance(MethodDescriptor.ofConstructor(HashMap.class));
for (Entry<DotName, Set<String>> entry : beanDeployment.getQualifierNonbindingMembers().entrySet()) {
Expand All @@ -143,9 +150,9 @@ Collection<Resource> generate(String name, BeanDeployment beanDeployment, Map<Be

ResultHandle componentsHandle = getComponents.newInstance(
MethodDescriptor.ofConstructor(Components.class, Collection.class, Collection.class, Collection.class,
Map.class, Collection.class, Map.class),
Map.class, Collection.class, Map.class, Set.class),
beansHandle, observersHandle, contextsHandle, transitiveBindingsHandle, removedBeansHandle,
qualifiersNonbindingMembers);
qualifiersNonbindingMembers, qualifiers);
getComponents.returnValue(componentsHandle);

// Finally write the bytecode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;

Expand All @@ -14,23 +13,19 @@ public final class Components {
private final Collection<InjectableContext> contexts;
private final Map<Class<? extends Annotation>, Set<Annotation>> transitiveInterceptorBindings;
private final Map<String, Set<String>> qualifierNonbindingMembers;

public Components(Collection<InjectableBean<?>> beans, Collection<InjectableObserverMethod<?>> observers,
Collection<InjectableContext> contexts,
Map<Class<? extends Annotation>, Set<Annotation>> transitiveInterceptorBindings) {
this(beans, observers, contexts, transitiveInterceptorBindings, Collections.emptyList(), Collections.emptyMap());
}
private final Set<String> qualifiers;

public Components(Collection<InjectableBean<?>> beans, Collection<InjectableObserverMethod<?>> observers,
Collection<InjectableContext> contexts,
Map<Class<? extends Annotation>, Set<Annotation>> transitiveInterceptorBindings,
Collection<RemovedBean> removedBeans, Map<String, Set<String>> qualifierNonbindingMembers) {
Collection<RemovedBean> removedBeans, Map<String, Set<String>> qualifierNonbindingMembers, Set<String> qualifiers) {
this.beans = beans;
this.observers = observers;
this.contexts = contexts;
this.transitiveInterceptorBindings = transitiveInterceptorBindings;
this.removedBeans = removedBeans;
this.qualifierNonbindingMembers = qualifierNonbindingMembers;
this.qualifiers = qualifiers;
}

public Collection<InjectableBean<?>> getBeans() {
Expand All @@ -53,8 +48,22 @@ public Collection<RemovedBean> getRemovedBeans() {
return removedBeans;
}

/**
* Values in the map are never null.
*
* @return a map of fully-qualified class names of all custom qualifiers to the set of non-binding members
* @see javax.enterprise.util.Nonbinding
*/
public Map<String, Set<String>> getQualifierNonbindingMembers() {
return qualifierNonbindingMembers;
}

/**
*
* @return the set of fully-qualified class names of all registered qualifiers
*/
public Set<String> getQualifiers() {
return qualifiers;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,15 @@ public class ArcContainerImpl implements ArcContainer {
private final List<InjectableDecorator<?>> decorators;
private final List<InjectableObserverMethod<?>> observers;
private final Map<Class<? extends Annotation>, Set<Annotation>> transitiveInterceptorBindings;
private final Map<String, Set<String>> qualifierNonbindingMembers;

private final Contexts contexts;

private final ComputingCache<Resolvable, Set<InjectableBean<?>>> resolved;
private final ComputingCache<String, InjectableBean<?>> beansById;
private final ComputingCache<String, Set<InjectableBean<?>>> beansByName;

private final ArrayList<ResourceReferenceProvider> resourceProviders;

final InstanceImpl<Object> instance;
final Qualifiers registeredQualifiers;

private volatile ExecutorService executorService;

Expand All @@ -105,6 +103,7 @@ public ArcContainerImpl(CurrentContextFactory currentContextFactory) {
List<InjectableObserverMethod<?>> observers = new ArrayList<>();
Map<Class<? extends Annotation>, Set<Annotation>> transitiveInterceptorBindings = new HashMap<>();
Map<String, Set<String>> qualifierNonbindingMembers = new HashMap<>();
Set<String> qualifiers = new HashSet<>();
this.currentContextFactory = currentContextFactory == null ? new ThreadLocalCurrentContextFactory()
: currentContextFactory;

Expand Down Expand Up @@ -139,6 +138,7 @@ public ArcContainerImpl(CurrentContextFactory currentContextFactory) {
}
transitiveInterceptorBindings.putAll(components.getTransitiveInterceptorBindings());
qualifierNonbindingMembers.putAll(components.getQualifierNonbindingMembers());
qualifiers.addAll(components.getQualifiers());
}

this.contexts = contextsBuilder.build();
Expand All @@ -165,7 +165,7 @@ public ArcContainerImpl(CurrentContextFactory currentContextFactory) {
this.observers = List.copyOf(observers);
this.removedBeans = List.copyOf(removedBeans);
this.transitiveInterceptorBindings = Map.copyOf(transitiveInterceptorBindings);
this.qualifierNonbindingMembers = Map.copyOf(qualifierNonbindingMembers);
this.registeredQualifiers = new Qualifiers(qualifiers, qualifierNonbindingMembers);
}

private static void addBuiltInBeans(List<InjectableBean<?>> beans) {
Expand Down Expand Up @@ -447,7 +447,7 @@ private <T> InjectableBean<T> getBean(Type requiredType, Annotation... qualifier
if (qualifiers == null || qualifiers.length == 0) {
qualifiers = new Annotation[] { Default.Literal.INSTANCE };
} else {
Qualifiers.verify(qualifiers, qualifierNonbindingMembers.keySet());
registeredQualifiers.verify(qualifiers);
}
Set<InjectableBean<?>> resolvedBeans = resolved.getValue(new Resolvable(requiredType, qualifiers));
return resolvedBeans.size() != 1 ? null : (InjectableBean<T>) resolvedBeans.iterator().next();
Expand All @@ -460,7 +460,7 @@ Set<Bean<?>> getBeans(Type requiredType, Annotation... qualifiers) {
if (qualifiers == null || qualifiers.length == 0) {
qualifiers = new Annotation[] { Default.Literal.INSTANCE };
} else {
Qualifiers.verify(qualifiers, qualifierNonbindingMembers.keySet());
registeredQualifiers.verify(qualifiers);
}
// This method does not cache the results
return Set.of(getMatchingBeans(new Resolvable(requiredType, qualifiers)).toArray(new Bean<?>[] {}));
Expand All @@ -475,10 +475,6 @@ Map<Class<? extends Annotation>, Set<Annotation>> getTransitiveInterceptorBindin
return transitiveInterceptorBindings;
}

Set<String> getCustomQualifiers() {
return qualifierNonbindingMembers.keySet();
}

boolean isScope(Class<? extends Annotation> annotationType) {
if (annotationType.isAnnotationPresent(Scope.class) || annotationType.isAnnotationPresent(NormalScope.class)) {
return true;
Expand Down Expand Up @@ -693,7 +689,7 @@ private static int compareAlternativeBeans(InjectableBean<?> bean1, InjectableBe

@SuppressWarnings("unchecked")
<T> List<InjectableObserverMethod<? super T>> resolveObservers(Type eventType, Set<Annotation> eventQualifiers) {
Qualifiers.verify(eventQualifiers, qualifierNonbindingMembers.keySet());
registeredQualifiers.verify(eventQualifiers);
if (observers.isEmpty()) {
return Collections.emptyList();
}
Expand All @@ -702,7 +698,7 @@ <T> List<InjectableObserverMethod<? super T>> resolveObservers(Type eventType, S
for (InjectableObserverMethod<?> observer : observers) {
if (EventTypeAssignabilityRules.instance().matches(observer.getObservedType(), eventTypes)) {
if (observer.getObservedQualifiers().isEmpty()
|| Qualifiers.isSubset(observer.getObservedQualifiers(), eventQualifiers, qualifierNonbindingMembers)) {
|| registeredQualifiers.isSubset(observer.getObservedQualifiers(), eventQualifiers)) {
resolvedObservers.add((InjectableObserverMethod<? super T>) observer);
}
}
Expand Down Expand Up @@ -757,7 +753,7 @@ private boolean hasAllInterceptionBindings(InjectableInterceptor<?> interceptor,
// The method or constructor has all the interceptor bindings of the interceptor
for (Annotation binding : interceptor.getInterceptorBindings()) {
// The resolution rules are the same for qualifiers
if (!Qualifiers.hasQualifier(bindings, binding, qualifierNonbindingMembers)) {
if (!registeredQualifiers.hasQualifier(bindings, binding)) {
return false;
}
}
Expand All @@ -774,6 +770,8 @@ private boolean hasAllInterceptionBindings(InjectableInterceptor<?> interceptor,
Set<InjectableBean<?>> getResolvedBeans(Type requiredType, Annotation... qualifiers) {
if (qualifiers == null || qualifiers.length == 0) {
qualifiers = new Annotation[] { Default.Literal.INSTANCE };
} else {
registeredQualifiers.verify(qualifiers);
}
return resolved.getValue(new Resolvable(requiredType, qualifiers));
}
Expand All @@ -786,15 +784,15 @@ private boolean matches(Set<Type> beanTypes, Set<Annotation> beanQualifiers, Typ
if (!BeanTypeAssignabilityRules.instance().matches(requiredType, beanTypes)) {
return false;
}
return Qualifiers.hasQualifiers(beanQualifiers, qualifierNonbindingMembers, qualifiers);
return registeredQualifiers.hasQualifiers(beanQualifiers, qualifiers);
}

private boolean decoratorMatches(Set<Type> beanTypes, Set<Annotation> beanQualifiers, Type delegateType,
Annotation... delegateQualifiers) {
if (!DelegateInjectionPointAssignabilityRules.instance().matches(delegateType, beanTypes)) {
return false;
}
return Qualifiers.hasQualifiers(beanQualifiers, qualifierNonbindingMembers, delegateQualifiers);
return registeredQualifiers.hasQualifiers(beanQualifiers, delegateQualifiers);
}

static ArcContainerImpl unwrap(ArcContainer container) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public boolean isPassivatingScope(Class<? extends Annotation> annotationType) {
@Override
public boolean isQualifier(Class<? extends Annotation> annotationType) {
return annotationType.isAnnotationPresent(Qualifier.class)
|| ArcContainerImpl.instance().getCustomQualifiers().contains(annotationType.getName());
|| ArcContainerImpl.instance().registeredQualifiers.isRegistered(annotationType);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,23 +120,23 @@ private Notifier<? super T> getNotifier(Class<?> runtimeType) {

@Override
public Event<T> select(Annotation... qualifiers) {
Qualifiers.verify(qualifiers, ArcContainerImpl.instance().getCustomQualifiers());
ArcContainerImpl.instance().registeredQualifiers.verify(qualifiers);
Set<Annotation> mergedQualifiers = new HashSet<>(this.qualifiers);
Collections.addAll(mergedQualifiers, qualifiers);
return new EventImpl<T>(eventType, mergedQualifiers);
}

@Override
public <U extends T> Event<U> select(Class<U> subtype, Annotation... qualifiers) {
Qualifiers.verify(qualifiers, ArcContainerImpl.instance().getCustomQualifiers());
ArcContainerImpl.instance().registeredQualifiers.verify(qualifiers);
Set<Annotation> mergerdQualifiers = new HashSet<>(this.qualifiers);
Collections.addAll(mergerdQualifiers, qualifiers);
return new EventImpl<U>(subtype, mergerdQualifiers);
}

@Override
public <U extends T> Event<U> select(TypeLiteral<U> subtype, Annotation... qualifiers) {
Qualifiers.verify(qualifiers, ArcContainerImpl.instance().getCustomQualifiers());
ArcContainerImpl.instance().registeredQualifiers.verify(qualifiers);
if (Types.containsTypeVariable(subtype.getType())) {
throw new IllegalArgumentException(
"Event#select(TypeLiteral, Annotation...) cannot be used with type variable parameter");
Expand Down
Loading

0 comments on commit 5a1eef0

Please sign in to comment.