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