Skip to content

Commit

Permalink
WELD-2774 Implement BM methods for event/bean assignability
Browse files Browse the repository at this point in the history
  • Loading branch information
manovotn committed Jan 23, 2024
1 parent f324a81 commit 37c418a
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,18 @@ public WeldInstance<Object> createInstance() {
return delegate().createInstance();
}

@Override
public boolean isMatchingBean(Set<Type> beanTypes, Set<Annotation> beanQualifiers, Type requiredType,
Set<Annotation> requiredQualifiers) {
return delegate().isMatchingBean(beanTypes, beanQualifiers, requiredType, requiredQualifiers);
}

@Override
public boolean isMatchingEvent(Type eventType, Set<Annotation> eventQualifiers, Type observedEventType,
Set<Annotation> observedEventQualifiers) {
return delegate().isMatchingEvent(eventType, eventQualifiers, observedEventType, observedEventQualifiers);
}

@Override
public Bean<?> getPassivationCapableBean(BeanIdentifier identifier) {
return delegate().getPassivationCapableBean(identifier);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import java.util.Set;

import jakarta.enterprise.context.Dependent;
import jakarta.enterprise.inject.Any;
import jakarta.enterprise.inject.Default;
import jakarta.enterprise.inject.spi.BeanAttributes;
import jakarta.enterprise.inject.spi.configurator.BeanAttributesConfigurator;
Expand Down Expand Up @@ -222,7 +221,8 @@ public BeanAttributesConfigurator<T> alternative(boolean alternative) {

@Override
public BeanAttributes<T> complete() {
return new ImmutableBeanAttributes<T>(ImmutableSet.copyOf(stereotypes), isAlternative, name, initQualifiers(qualifiers),
return new ImmutableBeanAttributes<T>(ImmutableSet.copyOf(stereotypes), isAlternative, name,
Bindings.normalizeBeanQualifiers(qualifiers),
ImmutableSet.copyOf(types),
initScope());
}
Expand Down Expand Up @@ -258,27 +258,4 @@ private Class<? extends Annotation> initScope() {
return Dependent.class;
}

private Set<Annotation> initQualifiers(Set<Annotation> qualifiers) {
if (qualifiers.isEmpty()) {
return Bindings.DEFAULT_QUALIFIERS;
}
Set<Annotation> normalized = new HashSet<Annotation>(qualifiers);
normalized.remove(Any.Literal.INSTANCE);
normalized.remove(Default.Literal.INSTANCE);
if (normalized.isEmpty()) {
normalized = Bindings.DEFAULT_QUALIFIERS;
} else {
ImmutableSet.Builder<Annotation> builder = ImmutableSet.builder();
if (normalized.size() == 1) {
if (normalized.iterator().next().annotationType().equals(Named.class)) {
builder.add(Default.Literal.INSTANCE);
}
}
builder.add(Any.Literal.INSTANCE);
builder.addAll(qualifiers);
normalized = builder.build();
}
return normalized;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,13 @@ public interface BeanManagerLogger extends WeldLogger {
@Message(id = 1336, value = "InjectionTargetFactory.configure() may not be called after createInjectionTarget() invocation. AnnotatedType used: {0}", format = Format.MESSAGE_FORMAT)
IllegalStateException unableToConfigureInjectionTargetFactory(Object param1);

@Message(id = 1337, value = "BeanContainer#{0} requires all parameters to be non-null.", format = Format.MESSAGE_FORMAT)
IllegalArgumentException assignabilityMethodIllegalArgs(Object param1);

@Message(id = 1338, value = "All annotations passed into BeanContainer#{0} have to be CDI Qualifiers. Following annotation was not recognized as a qualifier: {1}", format = Format.MESSAGE_FORMAT)
IllegalArgumentException annotationNotAQualifier(Object param1, Object param2);

@Message(id = 1339, value = "Provided event type {0} cannot contain unresolvable type parameter", format = Format.MESSAGE_FORMAT)
IllegalArgumentException eventTypeUnresolvableWildcard(Object param1);

}
72 changes: 72 additions & 0 deletions impl/src/main/java/org/jboss/weld/manager/BeanManagerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
import jakarta.enterprise.context.spi.Contextual;
import jakarta.enterprise.context.spi.CreationalContext;
import jakarta.enterprise.event.Event;
import jakarta.enterprise.inject.Any;
import jakarta.enterprise.inject.Default;
import jakarta.enterprise.inject.Instance;
import jakarta.enterprise.inject.spi.Annotated;
import jakarta.enterprise.inject.spi.AnnotatedField;
Expand Down Expand Up @@ -154,6 +156,7 @@
import org.jboss.weld.module.ObserverNotifierFactory;
import org.jboss.weld.resolution.BeanTypeAssignabilityRules;
import org.jboss.weld.resolution.DecoratorResolvableBuilder;
import org.jboss.weld.resolution.EventTypeAssignabilityRules;
import org.jboss.weld.resolution.InterceptorResolvable;
import org.jboss.weld.resolution.InterceptorResolvableBuilder;
import org.jboss.weld.resolution.NameBasedResolver;
Expand All @@ -177,9 +180,11 @@
import org.jboss.weld.util.LazyValueHolder;
import org.jboss.weld.util.Observers;
import org.jboss.weld.util.Preconditions;
import org.jboss.weld.util.Types;
import org.jboss.weld.util.collections.ImmutableSet;
import org.jboss.weld.util.collections.SetMultimap;
import org.jboss.weld.util.collections.WeldCollections;
import org.jboss.weld.util.reflection.HierarchyDiscovery;
import org.jboss.weld.util.reflection.Reflections;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
Expand Down Expand Up @@ -1563,6 +1568,73 @@ public WeldInstance<Object> createInstance() {
return getInstance(createCreationalContext(null));
}

@Override
public boolean isMatchingBean(Set<Type> beanTypes, Set<Annotation> beanQualifiers, Type requiredType,
Set<Annotation> requiredQualifiers) {
String loggingMethodName = "isMatchingBean()";
if (beanTypes == null || beanQualifiers == null || requiredType == null || requiredQualifiers == null) {
throw BeanManagerLogger.LOG.assignabilityMethodIllegalArgs(loggingMethodName);
}
validateQualifiers(beanQualifiers, loggingMethodName);
validateQualifiers(requiredQualifiers, loggingMethodName);
// always add Object as bean type; filter bean types to only contain legal bean types
Set<Type> legalBeanTypes = new HashSet<>(beanTypes);
legalBeanTypes.add(Object.class);
legalBeanTypes = Beans.getLegalBeanTypes(legalBeanTypes, beanTypes);
// type check first
if (BeanTypeAssignabilityRules.instance().matches(requiredType, legalBeanTypes)) {
// normalize qualifiers, adding built-ins where missing, then compare
Set<Annotation> normalizedBeanQualifiers = Bindings.normalizeBeanQualifiers(beanQualifiers);
Set<Annotation> normalizedRequiredQualifiers = requiredQualifiers.isEmpty() ? Set.of(Default.Literal.INSTANCE)
: requiredQualifiers;
MetaAnnotationStore metaAnnotationStore = services.get(MetaAnnotationStore.class);
if (Beans.containsAllQualifiers(QualifierInstance.of(normalizedRequiredQualifiers, metaAnnotationStore),
QualifierInstance.of(normalizedBeanQualifiers, metaAnnotationStore))) {
return true;
}
}
return false;
}

@Override
public boolean isMatchingEvent(Type eventType, Set<Annotation> eventQualifiers, Type observedEventType,
Set<Annotation> observedEventQualifiers) {
String loggingMethodName = "isMatchingEvent()";
if (eventType == null || eventQualifiers == null || observedEventType == null || observedEventQualifiers == null) {
throw BeanManagerLogger.LOG.assignabilityMethodIllegalArgs(loggingMethodName);
}
if (Types.containsTypeVariable(Types.getCanonicalType(eventType))) {
throw BeanManagerLogger.LOG.eventTypeUnresolvableWildcard(eventType);
}
validateQualifiers(eventQualifiers, loggingMethodName);
validateQualifiers(observedEventQualifiers, loggingMethodName);
// type check first
if (EventTypeAssignabilityRules.instance().matches(observedEventType,
HierarchyDiscovery.forNormalizedType(eventType).getTypeClosure())) {
// normalize qualifiers, adding built-ins where missing, then compare
Set<Annotation> normalizedEventQualifiers = new HashSet<>(eventQualifiers);
if (eventQualifiers.isEmpty()
|| (eventQualifiers.size() == 1 && eventQualifiers.iterator().next().equals(Any.Literal.INSTANCE))) {
normalizedEventQualifiers.add(Default.Literal.INSTANCE);
}
normalizedEventQualifiers.add(Any.Literal.INSTANCE);
MetaAnnotationStore metaAnnotationStore = services.get(MetaAnnotationStore.class);
if (Beans.containsAllQualifiers(QualifierInstance.of(observedEventQualifiers, metaAnnotationStore),
QualifierInstance.of(normalizedEventQualifiers, metaAnnotationStore))) {
return true;
}
}
return false;
}

private void validateQualifiers(Set<Annotation> qualifiers, String methodName) {
for (Annotation qualifierCandidate : qualifiers) {
if (!isQualifier(qualifierCandidate.annotationType())) {
throw BeanManagerLogger.LOG.annotationNotAQualifier(methodName, qualifierCandidate.annotationType());
}
}
}

private Bean<?> findNormalScopedDependant(CreationalContextImpl<?> weldCreationalContext) {
CreationalContextImpl<?> parent = weldCreationalContext.getParentCreationalContext();
if (parent != null) {
Expand Down
31 changes: 31 additions & 0 deletions impl/src/main/java/org/jboss/weld/util/Bindings.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@
package org.jboss.weld.util;

import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;

import jakarta.enterprise.inject.Any;
import jakarta.enterprise.inject.Default;
import jakarta.enterprise.inject.spi.BeanManager;
import jakarta.inject.Named;

import org.jboss.weld.logging.BeanManagerLogger;
import org.jboss.weld.logging.MetadataLogger;
Expand Down Expand Up @@ -102,4 +104,33 @@ private static void checkInterceptorBinding(Annotation qualifier, MetaAnnotation
throw BeanManagerLogger.LOG.interceptorResolutionWithNonbindingType(qualifier);
}
}

/**
* Normalize set of qualifiers for a bean - automatically adds {@code @Any} and {@code Default} if needed.
*
* @param qualifiers input set of qualifiers, possibly missing built-in qualifiers
* @return normalized set of bean qualifiers
*/
public static Set<Annotation> normalizeBeanQualifiers(Set<Annotation> qualifiers) {
if (qualifiers.isEmpty()) {
return DEFAULT_QUALIFIERS;
}
Set<Annotation> normalized = new HashSet<Annotation>(qualifiers);
normalized.remove(Any.Literal.INSTANCE);
normalized.remove(Default.Literal.INSTANCE);
if (normalized.isEmpty()) {
normalized = DEFAULT_QUALIFIERS;
} else {
ImmutableSet.Builder<Annotation> builder = ImmutableSet.builder();
if (normalized.size() == 1) {
if (normalized.iterator().next().annotationType().equals(Named.class)) {
builder.add(Default.Literal.INSTANCE);
}
}
builder.add(Any.Literal.INSTANCE);
builder.addAll(qualifiers);
normalized = builder.build();
}
return normalized;
}
}
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
<arquillian.tomcat.version>1.2.0.Final</arquillian.tomcat.version>
<atinject.tck.version>2.0.1</atinject.tck.version>
<!-- Version of the CDI 4.x release TCK -->
<cdi.tck-4-1.version>4.1.0-M1</cdi.tck-4-1.version>
<cdi.tck-4-1.version>4.1.0-SNAPSHOT</cdi.tck-4-1.version>
<!-- By default, each mvn profile uses corresponding file from TCK repo, see jboss-tck-runner/pom.xml -->
<!-- We can also use our own file, needed for relaxed mode testing (see WeldMethodInterceptor) -->
<!-- Our variant is under src/test/tck/tck-tests.xml -->
Expand Down Expand Up @@ -88,8 +88,8 @@
<shrinkwrap.version>1.2.6</shrinkwrap.version>
<shrinkwrap.descriptors.version>2.0.0</shrinkwrap.descriptors.version>
<shrinkwrap.resolver.version>3.3.0</shrinkwrap.resolver.version>
<testng.version>7.4.0</testng.version>
<weld.api.version>6.0.Alpha2</weld.api.version>
<testng.version>7.9.0</testng.version>
<weld.api.version>6.0-SNAPSHOT</weld.api.version>
<weld.logging.tools.version>1.0.3.Final</weld.logging.tools.version>
<wildfly.arquillian.version>5.0.1.Final</wildfly.arquillian.version>
</properties>
Expand Down

0 comments on commit 37c418a

Please sign in to comment.