io.helidon.integrations.micronaut.cdi.MicronautInterceptor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of helidon-integrations-micronaut-cdi Show documentation
Show all versions of helidon-integrations-micronaut-cdi Show documentation
Integration with Micronaut to be used in CDI environment.
The newest version!
/*
* Copyright (c) 2020, 2024 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.helidon.integrations.micronaut.cdi;
import java.lang.reflect.Method;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import io.micronaut.aop.MethodInterceptor;
import io.micronaut.context.ApplicationContext;
import io.micronaut.core.annotation.Internal;
import io.micronaut.inject.ExecutableMethod;
import jakarta.annotation.Priority;
import jakarta.inject.Inject;
import jakarta.interceptor.AroundInvoke;
import jakarta.interceptor.Interceptor;
import jakarta.interceptor.InvocationContext;
/**
* A CDI interceptor that invokes all Micronaut interceptors.
* DO NOT USE DIRECTLY. Usage is computed by this CDI extension.
*/
// interceptor binding is defined in code of extension, not on annotation
@MicronautIntercepted
@Interceptor
@Priority(Interceptor.Priority.LIBRARY_BEFORE)
@Internal
public class MicronautInterceptor {
private static final System.Logger LOGGER = System.getLogger(MicronautInterceptor.class.getName());
private final ApplicationContext context;
private final MicronautCdiExtension extension;
@Inject
MicronautInterceptor(ApplicationContext context, MicronautCdiExtension extension) {
this.context = context;
this.extension = extension;
}
/**
* Interceptor method that call Micronaut interceptors for a CDI bean.
*
* @param cdiCtx invocation context
* @return response of the method
*/
@SuppressWarnings({"rawtypes", "unchecked"})
@AroundInvoke
public Object invoke(InvocationContext cdiCtx) {
Method javaMethod = cdiCtx.getMethod();
MethodInterceptorMetadata meta = extension.getInterceptionMetadata(javaMethod);
Set>> interceptorClasses = meta.interceptors();
Set> interceptors = new TreeSet<>(Comparator.comparingInt(MethodInterceptor::getOrder));
for (Class extends MethodInterceptor> aClass : interceptorClasses) {
// we need to find the bean for each invocation, as this may be a prototype bean
interceptors.add(context.findBean(aClass)
.orElseThrow(() -> new MicronautCdiException("Cannot create bean class for interceptor "
+ aClass.getName())));
}
ExecutableMethod, ?> executableMethod = meta.executableMethod();
Iterator> remaining = interceptors.iterator();
io.micronaut.aop.MethodInvocationContext context = MicronautMethodInvocationContext
.create(cdiCtx, executableMethod, interceptors, remaining);
// There is always at least one interceptor, as otherwise this class would never be registered with CDI
MethodInterceptor, ?> next = remaining.next();
LOGGER.log(System.Logger.Level.TRACE, () -> "Micronaut interceptor: " + next.getClass().getName());
return next.intercept(context);
}
}