Skip to content

Commit

Permalink
WIP ArC: fix non-@inherited transitive bindings on @inherited bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
Ladicek committed Sep 19, 2024
1 parent 04deb1d commit 8d753f1
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -686,11 +686,24 @@ Collection<AnnotationInstance> extractQualifiers(AnnotationInstance annotation)
* @return a collection of interceptor bindings or an empty collection
*/
public Collection<AnnotationInstance> extractInterceptorBindings(AnnotationInstance annotation) {
return extractInterceptorBindings(annotation, false);
}

Collection<AnnotationInstance> extractInterceptorBindings(AnnotationInstance annotation, boolean onlyInherited) {
Collection<AnnotationInstance> result = extractAnnotations(annotation, interceptorBindings,
repeatingInterceptorBindingAnnotations);
if (result.isEmpty()) {
return result;
}
if (onlyInherited) {
Set<AnnotationInstance> modifiedResult = new HashSet<>();
for (AnnotationInstance ann : result) {
if (hasAnnotation(getInterceptorBinding(ann.name()), DotNames.INHERITED)) {
modifiedResult.add(ann);
}
}
result = modifiedResult;
}
Set<AnnotationInstance> transitive = transitiveInterceptorBindings.get(annotation.name());
if (transitive != null) {
result = new HashSet<>(result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -922,10 +922,8 @@ private void addClassLevelBindings(ClassInfo targetClass, Collection<AnnotationI
private void doAddClassLevelBindings(ClassInfo classInfo, Collection<AnnotationInstance> bindings, Set<DotName> skip,
boolean onlyInherited) {
beanDeployment.getAnnotations(classInfo).stream()
.flatMap(a -> beanDeployment.extractInterceptorBindings(a).stream())
.flatMap(a -> beanDeployment.extractInterceptorBindings(a, onlyInherited).stream())
.filter(a -> !skip.contains(a.name()))
.filter(a -> !onlyInherited
|| beanDeployment.hasAnnotation(beanDeployment.getInterceptorBinding(a.name()), DotNames.INHERITED))
.forEach(bindings::add);
if (classInfo.superClassType() != null && !classInfo.superClassType().name().equals(DotNames.OBJECT)) {
ClassInfo superClass = getClassByName(beanDeployment.getBeanArchiveIndex(), classInfo.superName());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package io.quarkus.arc.test.interceptors.bindings.inherited.transitive;

import io.quarkus.arc.Arc;
import io.quarkus.arc.test.ArcTestContainer;
import jakarta.annotation.Priority;
import jakarta.inject.Singleton;
import jakarta.interceptor.AroundInvoke;
import jakarta.interceptor.Interceptor;
import jakarta.interceptor.InterceptorBinding;
import jakarta.interceptor.InvocationContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InheritedTransitiveBindingOnBeanTest {
@RegisterExtension
public ArcTestContainer container = new ArcTestContainer.Builder()
.beanClasses(MyBean.class, FooBinding.class, BarBinding.class, BazBinding.class, FooInterceptor.class, BarInterceptor.class, BazInterceptor.class)
.build();

@Test
public void testInterception() {
MyBean bean = Arc.container().instance(MyBean.class).get();
assertNotNull(bean);
bean.doSomething();
assertTrue(FooInterceptor.intercepted);
assertFalse(BarInterceptor.intercepted);
assertTrue(BazInterceptor.intercepted);
}

@FooBinding
@BarBinding
static class MySuperclass {
}

@Singleton
static class MyBean extends MySuperclass {
void doSomething() {
}
}

@BazBinding
@Target({ TYPE, METHOD })
@Retention(RUNTIME)
@Documented
@InterceptorBinding
@Inherited
@interface FooBinding {
}

@Target({ TYPE, METHOD })
@Retention(RUNTIME)
@Documented
@InterceptorBinding
// not @Inherited
@interface BarBinding {
}

@Target({ TYPE, METHOD })
@Retention(RUNTIME)
@Documented
@InterceptorBinding
// not @Inherited
@interface BazBinding {
}

@FooBinding
@Interceptor
@Priority(1)
static class FooInterceptor {
static boolean intercepted = false;

@AroundInvoke
Object intercept(InvocationContext ctx) throws Exception {
intercepted = true;
return ctx.proceed();
}
}

@BarBinding
@Interceptor
@Priority(1)
static class BarInterceptor {
static boolean intercepted = false;

@AroundInvoke
Object intercept(InvocationContext ctx) throws Exception {
intercepted = true;
return ctx.proceed();
}
}

@BazBinding
@Interceptor
@Priority(1)
static class BazInterceptor {
static boolean intercepted = false;

@AroundInvoke
Object intercept(InvocationContext ctx) throws Exception {
intercepted = true;
return ctx.proceed();
}
}
}

0 comments on commit 8d753f1

Please sign in to comment.