public BeanInterceptorInfo calculateInterceptorInfo()

in webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorResolutionService.java [96:253]


    public <T> BeanInterceptorInfo  calculateInterceptorInfo(Set<Type> beanTypes, Set<Annotation> qualifiers, AnnotatedType<T> annotatedType,
                                                             boolean failOnFinal)
    {
        Asserts.assertNotNull(beanTypes, "beanTypes");
        Asserts.assertNotNull(qualifiers, "qualifiers");
        Asserts.assertNotNull(annotatedType, "AnnotatedType");

        List<AnnotatedMethod> interceptableAnnotatedMethods = getInterceptableBusinessMethods(annotatedType);

        AnnotationManager annotationManager = webBeansContext.getAnnotationManager();
        BeanManagerImpl beanManager = webBeansContext.getBeanManagerImpl();


        // pick up EJB-style interceptors from a class level
        List<Interceptor<?>> classLevelEjbInterceptors = new ArrayList<>();

        collectEjbInterceptors(classLevelEjbInterceptors, annotatedType, false, beanTypes);

        // pick up the decorators
        List<Decorator<?>> decorators = beanManager.unsafeResolveDecorators(beanTypes, AnnotationUtil.asArray(qualifiers));
        if (decorators.isEmpty())
        {
            decorators = Collections.emptyList(); // less to store
        }

        Set<Interceptor<?>> allUsedCdiInterceptors = new HashSet<>();

        // pick up CDI interceptors from a class level
        Set<Annotation> classInterceptorBindings = annotationManager.getInterceptorAnnotations(annotatedType.getAnnotations());
        List<Interceptor<?>> classLevelInterceptors;
        if (classInterceptorBindings.size() > 0)
        {
            classLevelInterceptors = webBeansContext.getBeanManagerImpl().resolveInterceptors(InterceptionType.AROUND_INVOKE, AnnotationUtil.asArray(classInterceptorBindings));
            allUsedCdiInterceptors.addAll(classLevelInterceptors);
        }
        else
        {
            classLevelInterceptors = Collections.EMPTY_LIST;
        }

        Set<Interceptor<?>> allUsedConstructorCdiInterceptors = new HashSet<>();
        addCdiClassLifecycleInterceptors(annotatedType, classInterceptorBindings, allUsedCdiInterceptors, allUsedConstructorCdiInterceptors);

        LinkedHashSet<Interceptor<?>> allUsedEjbInterceptors = new LinkedHashSet<>(); // we need to preserve the order!
        allUsedEjbInterceptors.addAll(classLevelEjbInterceptors);

        Map<Method, BusinessMethodInterceptorInfo> businessMethodInterceptorInfos = new HashMap<>();
        Map<Constructor<?>, BusinessMethodInterceptorInfo> constructorInterceptorInfos = new HashMap<>();

        List<Interceptor<?>> classCdiInterceptors = new ArrayList<>(allUsedCdiInterceptors);
        classCdiInterceptors.sort(new InterceptorComparator(webBeansContext));

        List<Method> nonInterceptedMethods = new ArrayList<>();

        SelfInterceptorBean<T> selfInterceptorBean = resolveSelfInterceptorBean(annotatedType);

        // iterate over all methods and build up the interceptor/decorator stack
        for (AnnotatedMethod annotatedMethod : interceptableAnnotatedMethods)
        {
            BusinessMethodInterceptorInfo methodInterceptorInfo = new BusinessMethodInterceptorInfo();

            calculateEjbMethodInterceptors(methodInterceptorInfo, allUsedEjbInterceptors, classLevelEjbInterceptors, annotatedMethod, failOnFinal);

            calculateCdiMethodInterceptors(methodInterceptorInfo, InterceptionType.AROUND_INVOKE, allUsedCdiInterceptors, annotatedMethod,
                                           classInterceptorBindings, classLevelInterceptors, failOnFinal);

            calculateCdiMethodDecorators(methodInterceptorInfo, decorators, annotatedMethod, failOnFinal);

            if (methodInterceptorInfo.isEmpty() && (selfInterceptorBean == null || !selfInterceptorBean.isAroundInvoke()))
            {
                nonInterceptedMethods.add(annotatedMethod.getJavaMember());
                continue;
            }

            businessMethodInterceptorInfos.put(annotatedMethod.getJavaMember(), methodInterceptorInfo);
        }
        for (AnnotatedConstructor annotatedConstructor : annotatedType.getConstructors())
        {
            BusinessMethodInterceptorInfo constructorInterceptorInfo = new BusinessMethodInterceptorInfo();
            calculateEjbMethodInterceptors(constructorInterceptorInfo, allUsedEjbInterceptors, classLevelEjbInterceptors, annotatedConstructor, failOnFinal);
            if (constructorInterceptorInfo.isEmpty() && (selfInterceptorBean == null || !selfInterceptorBean.isAroundInvoke()))
            {
                continue;
            }

            constructorInterceptorInfos.put(annotatedConstructor.getJavaMember(), constructorInterceptorInfo);
        }

        Map<InterceptionType, LifecycleMethodInfo> lifecycleMethodInterceptorInfos
                = new HashMap<>();

        addLifecycleMethods(
                lifecycleMethodInterceptorInfos,
                annotatedType,
                InterceptionType.POST_CONSTRUCT,
                PostConstruct.class,
                allUsedCdiInterceptors,
                allUsedEjbInterceptors,
                classLevelEjbInterceptors,
                classInterceptorBindings,
                failOnFinal);

        addLifecycleMethods(
                lifecycleMethodInterceptorInfos,
                annotatedType,
                InterceptionType.PRE_DESTROY,
                PreDestroy.class,
                allUsedCdiInterceptors,
                allUsedEjbInterceptors,
                classLevelEjbInterceptors,
                classInterceptorBindings,
                failOnFinal);

        List<Interceptor<?>> cdiInterceptors = new ArrayList<>(allUsedCdiInterceptors);
        cdiInterceptors.sort(new InterceptorComparator(webBeansContext));

        List<Interceptor<?>> cdiConstructorInterceptors = new ArrayList<>(allUsedConstructorCdiInterceptors);
        cdiConstructorInterceptors.sort(new InterceptorComparator(webBeansContext));

        boolean interceptedBean = !annotatedType.getJavaClass().isInterface() && (
                                      allUsedEjbInterceptors.size() > 0 ||
                                      allUsedCdiInterceptors.size() > 0 ||
                                      lifecycleMethodInterceptorInfos.size() > 0
                                  );

        if ((interceptedBean || decorators.size() > 0) && Modifier.isFinal(annotatedType.getJavaClass().getModifiers()))
        {
            throw new WebBeansDeploymentException("Cannot apply Decorators or Interceptors on a final class: "
                                                     + annotatedType.getJavaClass().getName());
        }

        // if we have an interceptedBean, the bean must be proxyable in any case (also @Dependent)
        if (interceptedBean)
        {
            boolean proxyable = false;
            for (AnnotatedConstructor<T> constructor : annotatedType.getConstructors())
            {
                if ((constructor.getParameters().isEmpty() && !isUnproxyable(constructor, failOnFinal)) ||
                     constructor.isAnnotationPresent(Inject.class))
                {
                    proxyable = true;
                    break;
                }
            }

            if (!proxyable)
            {
                throw new WebBeansDeploymentException("Intercepted Bean " + annotatedType.getBaseType() + " must be proxyable");
            }
        }

        return new BeanInterceptorInfo(decorators, allUsedEjbInterceptors,
                                       cdiInterceptors, cdiConstructorInterceptors,
                                       selfInterceptorBean,
                                       constructorInterceptorInfos, businessMethodInterceptorInfos,
                                       nonInterceptedMethods, lifecycleMethodInterceptorInfos,
                                       classCdiInterceptors);
    }