Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ArC: update annotation transformation documentation #41149

Merged
merged 1 commit into from
Jun 12, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 24 additions & 22 deletions docs/src/main/asciidoc/cdi-integration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -166,23 +166,23 @@
Quarkus provides a powerful alternative to https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#process_annotated_type[`jakarta.enterprise.inject.spi.ProcessAnnotatedType`, window="_blank"] and https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#bce_enhancement[`jakarta.enterprise.inject.build.compatible.spi.Enhancement`, window="_blank"].
With an `AnnotationsTransformerBuildItem` it's possible to override the annotations that exist on bean classes.

NOTE: Keep in mind that annotation transformers must be produced _before_ the bean discovery starts.

Check warning on line 169 in docs/src/main/asciidoc/cdi-integration.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsWarnings] Consider using 'remember' rather than 'Keep in mind' unless updating existing content that uses the term. Raw Output: {"message": "[Quarkus.TermsWarnings] Consider using 'remember' rather than 'Keep in mind' unless updating existing content that uses the term.", "location": {"path": "docs/src/main/asciidoc/cdi-integration.adoc", "range": {"start": {"line": 169, "column": 7}}}, "severity": "WARNING"}

For example, you might want to add an interceptor binding to a specific bean class.
You can use a convenient builder-like API to create a transformer instance:
You can use a convenient builder API to create a transformation instance:

Builder Example
.Builder Example
[source,java]
----
@BuildStep
AnnotationsTransformerBuildItem transform() {
return new AnnotationsTransformerBuildItem(AnnotationsTransformer.appliedToClass() <1>
.whenClass(c -> c.name().toString().equals("org.acme.Bar")) <2>
.thenTransform(t -> t.add(MyInterceptorBinding.class))); <3>
return new AnnotationsTransformerBuildItem(AnnotationTransformation.forClasses() // <1>
.whenClass(DotName.createSimple("org.acme.Bar")) // <2>
.transform(t -> t.add(MyInterceptorBinding.class))); // <3>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the future, IIRC, you don't need the //. The callouts are automatically removed when you copy/paste the code.
It doesn't hurt though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know they are not necessary, but they help IDEA understand the code. That's why I've been using them everywhere :-)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, makes sense then!

}
----
<1> The transformer is only applied to classes.
<2> Only apply the transformation if the class name equals to `org.acme.Bar`.
<2> Only apply the transformation if the class is `org.acme.Bar`.
<3> Add the `@MyInterceptorBinding` annotation.

The example above can be rewritten with an anonymous class:
Expand All @@ -192,34 +192,36 @@
----
@BuildStep
AnnotationsTransformerBuildItem transform() {
return new AnnotationsTransformerBuildItem(new AnnotationsTransformer() {

public boolean appliesTo(org.jboss.jandex.AnnotationTarget.Kind kind) {
return kind == org.jboss.jandex.AnnotationTarget.Kind.CLASS; <1>
}
return new AnnotationsTransformerBuildItem(new AnnotationTransformation() {
public boolean supports(AnnotationTarget.Kind kind) {
return kind == AnnotationTarget.Kind.CLASS; // <1>
}

public void transform(TransformationContext context) {
if (context.getTarget().asClass().name().toString().equals("org.acme.Bar")) {
context.transform().add(MyInterceptorBinding.class).done(); <2>
}
}
public void apply(TransformationContext context) {
if (context.declaration().asClass().name().toString().equals("org.acme.Bar")) {
context.add(MyInterceptorBinding.class); // <2>
}
}
});
}
----
<1> The transformer is only applied to classes.
<2> If the class name equals to `org.acme.Bar` then add `@MyInterceptorBinding`. Don't forget to invoke `Transformation#done()`.
<2> If the class name equals to `org.acme.Bar` then add `@MyInterceptorBinding`.

NOTE: The previous `AnnotationsTransformer` API from ArC is still supported, but the new `AnnotationTransformation` API from Jandex is preferred.

Build steps can query the transformed annotations for a given annotation target via the `TransformedAnnotationsBuildItem`.

Check warning on line 213 in docs/src/main/asciidoc/cdi-integration.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsWarnings] Consider using 'through', 'by', 'from', 'on', or 'by using' rather than 'via' unless updating existing content that uses the term. Raw Output: {"message": "[Quarkus.TermsWarnings] Consider using 'through', 'by', 'from', 'on', or 'by using' rather than 'via' unless updating existing content that uses the term.", "location": {"path": "docs/src/main/asciidoc/cdi-integration.adoc", "range": {"start": {"line": 213, "column": 81}}}, "severity": "WARNING"}

.`TransformedAnnotationsBuildItem` Example
[source,java]
----
@BuildStep
void queryAnnotations(TransformedAnnotationsBuildItem transformedAnnotations, BuildProducer<MyBuildItem> myBuildItem) {
ClassInfo myClazz = ...;
if (transformedAnnotations.getAnnotations(myClazz).isEmpty()) { <1>
myBuildItem.produce(new MyBuildItem());
}
void queryAnnotations(TransformedAnnotationsBuildItem transformedAnnotations,
BuildProducer<MyBuildItem> myBuildItem) {
ClassInfo myClazz = ...;
if (transformedAnnotations.getAnnotations(myClazz).isEmpty()) { // <1>
myBuildItem.produce(new MyBuildItem());
}
}
----
<1> `TransformedAnnotationsBuildItem.getAnnotations()` will return a possibly transformed set of annotations.
Expand Down