All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.helidon.integrations.micronaut.cdi.MicronautInterceptor Maven / Gradle / Ivy

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 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);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy