Skip to content

Commit 696ada1

Browse files
authored
Merge pull request #34138 from mkouba/synthetic-interceptors
ArC: add synthetic interceptors API
2 parents 1c37eee + f5994eb commit 696ada1

File tree

10 files changed

+485
-34
lines changed

10 files changed

+485
-34
lines changed

independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import jakarta.enterprise.event.Reception;
3030
import jakarta.enterprise.inject.spi.DefinitionException;
3131
import jakarta.enterprise.inject.spi.DeploymentException;
32+
import jakarta.enterprise.inject.spi.InterceptionType;
3233

3334
import org.jboss.jandex.AnnotationInstance;
3435
import org.jboss.jandex.AnnotationTarget;
@@ -1414,6 +1415,10 @@ private void addSyntheticBean(BeanInfo bean) {
14141415
beans.add(bean);
14151416
}
14161417

1418+
void addSyntheticInterceptor(InterceptorInfo interceptor) {
1419+
interceptors.add(interceptor);
1420+
}
1421+
14171422
private void addSyntheticObserver(ObserverConfigurator configurator) {
14181423
observers.add(ObserverInfo.create(configurator.id, this, configurator.beanClass, null, null, null, null,
14191424
configurator.observedType,
@@ -1688,6 +1693,20 @@ public <T> BeanConfigurator<T> configure(DotName beanClassName) {
16881693
return new BeanConfigurator<T>(beanClassName, beanDeployment, this);
16891694
}
16901695

1696+
@Override
1697+
public InterceptorConfigurator configureInterceptor(InterceptionType interceptionType) {
1698+
switch (Objects.requireNonNull(interceptionType)) {
1699+
case AROUND_INVOKE:
1700+
case POST_CONSTRUCT:
1701+
case PRE_DESTROY:
1702+
case AROUND_CONSTRUCT:
1703+
return new InterceptorConfigurator(beanDeployment, interceptionType);
1704+
default:
1705+
throw new IllegalArgumentException("Unsuppored interception type: " + interceptionType);
1706+
}
1707+
1708+
}
1709+
16911710
@Override
16921711
public void accept(BeanInfo bean) {
16931712
beanDeployment.addSyntheticBean(bean);

independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanGenerator.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,9 @@ public BeanGenerator(AnnotationLiteralProcessor annotationLiterals, Predicate<Do
126126
* @return a collection of resources
127127
*/
128128
Collection<Resource> generate(BeanInfo bean) {
129-
if (bean.getTarget().isPresent()) {
129+
if (bean.isSynthetic()) {
130+
return generateSyntheticBean(bean);
131+
} else {
130132
AnnotationTarget target = bean.getTarget().get();
131133
switch (target.kind()) {
132134
case CLASS:
@@ -138,9 +140,6 @@ Collection<Resource> generate(BeanInfo bean) {
138140
default:
139141
throw new IllegalArgumentException("Unsupported bean type");
140142
}
141-
} else {
142-
// Synthetic beans
143-
return generateSyntheticBean(bean);
144143
}
145144
}
146145

independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanRegistrar.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import java.util.Collection;
44

5+
import jakarta.enterprise.inject.spi.InterceptionType;
6+
57
import org.jboss.jandex.DotName;
68

79
/**
@@ -39,6 +41,15 @@ default <T> BeanConfigurator<T> configure(Class<?> beanClass) {
3941
return configure(DotName.createSimple(beanClass.getName()));
4042
}
4143

44+
/**
45+
* Configure a new synthetic interceptor. The interceptor is not added to the deployment unless the
46+
* {@link InterceptorConfigurator#creator(Class)} method is called.
47+
*
48+
* @param interceptionType
49+
* @return a new synthetic interceptor configurator
50+
*/
51+
InterceptorConfigurator configureInterceptor(InterceptionType interceptionType);
52+
4253
/**
4354
* The returned stream contains all non-synthetic beans (beans derived from classes) and beans
4455
* registered by other {@link BeanRegistrar}s before the stream is created.

independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Injection.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,21 @@ public class Injection {
4444
private static final Logger LOGGER = Logger.getLogger(Injection.class);
4545

4646
static Injection forSyntheticBean(Iterable<TypeAndQualifiers> injectionPoints) {
47-
List<InjectionPointInfo> ips = new ArrayList<>();
47+
return forSynthetic(injectionPoints, BeanType.SYNTHETIC_BEAN);
48+
}
49+
50+
static Injection forSyntheticInterceptor(Iterable<TypeAndQualifiers> injectionPoints) {
51+
return forSynthetic(injectionPoints, BeanType.SYNTHETIC_INTERCEPTOR);
52+
}
53+
54+
private static Injection forSynthetic(Iterable<TypeAndQualifiers> injectionPoints, BeanType beanType) {
55+
List<InjectionPointInfo> ret = new ArrayList<>();
4856
for (TypeAndQualifiers injectionPoint : injectionPoints) {
49-
InjectionPointInfo injectionPointInfo = InjectionPointInfo.fromSyntheticInjectionPoint(injectionPoint);
50-
validateInjections(injectionPointInfo, BeanType.SYNTHETIC_BEAN);
51-
ips.add(injectionPointInfo);
57+
InjectionPointInfo ip = InjectionPointInfo.fromSyntheticInjectionPoint(injectionPoint);
58+
validateInjections(ip, beanType);
59+
ret.add(ip);
5260
}
53-
return new Injection(null, ips);
61+
return new Injection(null, ret);
5462
}
5563

5664
private static void validateInjections(InjectionPointInfo injectionPointInfo, BeanType beanType) {
@@ -78,7 +86,8 @@ private static void validateInjections(InjectionPointInfo injectionPointInfo, Be
7886
// declaring the injection point
7987
if (injectionPointInfo.getRequiredType().name().equals(DotNames.BEAN)
8088
&& injectionPointInfo.getRequiredType().kind() == Type.Kind.PARAMETERIZED_TYPE
81-
&& injectionPointInfo.getRequiredType().asParameterizedType().arguments().size() == 1) {
89+
&& injectionPointInfo.getRequiredType().asParameterizedType().arguments().size() == 1
90+
&& injectionPointInfo.hasDefaultedQualifier()) {
8291
Type actualType = injectionPointInfo.getRequiredType().asParameterizedType().arguments().get(0);
8392
AnnotationTarget ipTarget = injectionPointInfo.getTarget();
8493
DotName expectedType = null;
@@ -255,6 +264,7 @@ static enum BeanType {
255264
PRODUCER_METHOD,
256265
SYNTHETIC_BEAN,
257266
INTERCEPTOR,
267+
SYNTHETIC_INTERCEPTOR,
258268
DECORATOR
259269
}
260270

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package io.quarkus.arc.processor;
2+
3+
import java.util.Collections;
4+
import java.util.HashSet;
5+
import java.util.List;
6+
import java.util.Set;
7+
8+
import jakarta.enterprise.inject.Default;
9+
import jakarta.enterprise.inject.spi.InterceptionType;
10+
11+
import org.jboss.jandex.AnnotationInstance;
12+
import org.jboss.jandex.Type;
13+
14+
import io.quarkus.arc.InterceptorCreator;
15+
import io.quarkus.arc.processor.InjectionPointInfo.TypeAndQualifiers;
16+
17+
/**
18+
* This construct is not thread-safe.
19+
*/
20+
public final class InterceptorConfigurator extends ConfiguratorBase<InterceptorConfigurator> {
21+
22+
private final BeanDeployment beanDeployment;
23+
24+
final InterceptionType type;
25+
final Set<TypeAndQualifiers> injectionPoints;
26+
final Set<AnnotationInstance> bindings;
27+
int priority;
28+
29+
InterceptorConfigurator(BeanDeployment beanDeployment, InterceptionType type) {
30+
this.beanDeployment = beanDeployment;
31+
this.type = type;
32+
this.injectionPoints = new HashSet<>();
33+
this.bindings = new HashSet<>();
34+
this.priority = 1;
35+
}
36+
37+
public InterceptorConfigurator priority(int priority) {
38+
this.priority = priority;
39+
return this;
40+
}
41+
42+
public InterceptorConfigurator bindings(AnnotationInstance... bindings) {
43+
Collections.addAll(this.bindings, bindings);
44+
return this;
45+
}
46+
47+
public InterceptorConfigurator addInjectionPoint(Type requiredType, AnnotationInstance... requiredQualifiers) {
48+
this.injectionPoints.add(new TypeAndQualifiers(requiredType,
49+
requiredQualifiers.length == 0 ? Set.of(AnnotationInstance.builder(Default.class).build())
50+
: Set.of(requiredQualifiers)));
51+
return this;
52+
}
53+
54+
public void creator(Class<? extends InterceptorCreator> creatorClass) {
55+
beanDeployment.addSyntheticInterceptor(new InterceptorInfo(creatorClass, beanDeployment, bindings,
56+
List.of(Injection.forSyntheticInterceptor(injectionPoints)), priority, type, params));
57+
}
58+
59+
}

0 commit comments

Comments
 (0)