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

org.apache.webbeans.intercept.InterceptorResolutionService Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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 org.apache.webbeans.intercept;

import org.apache.webbeans.annotation.AnnotationManager;
import org.apache.webbeans.component.BeanAttributesImpl;
import org.apache.webbeans.component.SelfInterceptorBean;
import org.apache.webbeans.component.creation.BeanAttributesBuilder;
import org.apache.webbeans.component.creation.SelfInterceptorBeanBuilder;
import org.apache.webbeans.config.OpenWebBeansConfiguration;
import org.apache.webbeans.config.WebBeansContext;
import org.apache.webbeans.container.BeanManagerImpl;
import org.apache.webbeans.exception.WebBeansConfigurationException;
import org.apache.webbeans.util.AnnotationUtil;
import org.apache.webbeans.util.Asserts;
import org.apache.webbeans.util.CDI11s;
import org.apache.webbeans.util.ClassUtil;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedParameter;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.Decorator;
import javax.enterprise.inject.spi.InterceptionType;
import javax.enterprise.inject.spi.Interceptor;
import javax.interceptor.ExcludeClassInterceptors;
import javax.interceptor.Interceptors;
import javax.interceptor.InvocationContext;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Class to calculate interceptor resolution information.
 * It also handles the proxy caching and applying.
 */
public class InterceptorResolutionService
{
    private final WebBeansContext webBeansContext;

    /**
     * Enforcing that interceptor callbacks should not be
     * able to throw checked exceptions is configurable
     */
    private static volatile Boolean enforceCheckedException;


    public InterceptorResolutionService(WebBeansContext webBeansContext)
    {
        this.webBeansContext = webBeansContext;
    }


    public  BeanInterceptorInfo  calculateInterceptorInfo(Set beanTypes, Set qualifiers, AnnotatedType annotatedType)
    {
        Asserts.assertNotNull(beanTypes, "beanTypes must not be null!");
        Asserts.assertNotNull(qualifiers, "qualifiers must not be null!");
        Asserts.assertNotNull(annotatedType, "AnnotatedType must not be null!");

        List interceptableAnnotatedMethods = getInterceptableBusinessMethods(annotatedType);

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


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

        collectEjbInterceptors(classLevelEjbInterceptors, annotatedType, false, beanTypes);

        // pick up the decorators
        List> decorators = beanManager.resolveDecorators(beanTypes, AnnotationUtil.asArray(qualifiers));
        if (decorators.size() == 0)
        {
            decorators = Collections.emptyList(); // less to store
        }

        // pick up CDI interceptors from a class level
        Set classInterceptorBindings = annotationManager.getInterceptorAnnotations(annotatedType.getAnnotations());
        Set> allUsedCdiInterceptors = new HashSet>();
        addCdiClassLifecycleInterceptors(classInterceptorBindings, allUsedCdiInterceptors);

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

        Map businessMethodInterceptorInfos = new HashMap();

        List nonInterceptedMethods = new ArrayList();

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

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

            calculateCdiMethodDecorators(methodInterceptorInfo, decorators, annotatedMethod);

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

            businessMethodInterceptorInfos.put(annotatedMethod.getJavaMember(), methodInterceptorInfo);
        }

        Map lifecycleMethodInterceptorInfos
                = new HashMap();

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

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

        List> cdiInterceptors = new ArrayList>(allUsedCdiInterceptors);
        Collections.sort(cdiInterceptors, new InterceptorComparator(webBeansContext));

        if (Modifier.isFinal(annotatedType.getJavaClass().getModifiers()) &&
            (allUsedEjbInterceptors.size() > 0 || 
             allUsedCdiInterceptors.size() > 0 || 
             lifecycleMethodInterceptorInfos.size() > 0 ||
             (decorators != null && decorators.size() > 0)))
        {
            throw new WebBeansConfigurationException("Cannot apply Decorators or Interceptors on a final class: " 
                                                     + annotatedType.getJavaClass().getName());
        }
        
        return new BeanInterceptorInfo(decorators, allUsedEjbInterceptors, cdiInterceptors, selfInterceptorBean,
                                       businessMethodInterceptorInfos,
                                       nonInterceptedMethods, lifecycleMethodInterceptorInfos);
    }

    /**
     * Lifycycle methods like {@link javax.annotation.PostConstruct} and
     * {@link javax.annotation.PreDestroy} must not define a checked Exception
     * regarding to the spec. But this is often unnecessary restrictive so we
     * allow to disable this check application wide.
     *
     * @return true if the spec rule of having no checked exception should be enforced
     */
    private boolean isNoCheckedExceptionEnforced()
    {
        if (enforceCheckedException == null)
        {
            enforceCheckedException = Boolean.parseBoolean(webBeansContext.getOpenWebBeansConfiguration().
                    getProperty(OpenWebBeansConfiguration.INTERCEPTOR_FORCE_NO_CHECKED_EXCEPTIONS, "true"));
        }

        return enforceCheckedException;
    }


    private void addCdiClassLifecycleInterceptors(Set classInterceptorBindings, Set> allUsedCdiInterceptors)
    {
        if (classInterceptorBindings.size() > 0)
        {
            final Annotation[] interceptorBindings = AnnotationUtil.asArray(classInterceptorBindings);
            final BeanManagerImpl beanManagerImpl = webBeansContext.getBeanManagerImpl();

            allUsedCdiInterceptors.addAll(beanManagerImpl.resolveInterceptors(InterceptionType.POST_CONSTRUCT, interceptorBindings));
            allUsedCdiInterceptors.addAll(beanManagerImpl.resolveInterceptors(InterceptionType.PRE_DESTROY, interceptorBindings));
            if (CDI11s.AROUND_CONSTRUCT != null)
            {
                allUsedCdiInterceptors.addAll(beanManagerImpl.resolveInterceptors(CDI11s.AROUND_CONSTRUCT, interceptorBindings));
            }
        }
    }

    /**
     * Check whether this class has any method which intercepts the whole bean itself.
     * @return SelfInterceptorBean or null if this bean doesn't intercept itself
     */
    private  SelfInterceptorBean resolveSelfInterceptorBean(AnnotatedType annotatedType)
    {
        BeanAttributesImpl beanAttributes = BeanAttributesBuilder.forContext(webBeansContext).newBeanAttibutes(annotatedType).build();
        SelfInterceptorBeanBuildersibb = new SelfInterceptorBeanBuilder(webBeansContext, annotatedType, beanAttributes);
        sibb.defineSelfInterceptorRules();
        if (!sibb.isInterceptorEnabled())
        {
            return null;
        }

        return sibb.getBean();
    }

    private void addLifecycleMethods(Map lifecycleMethodInterceptorInfos,
                                     AnnotatedType annotatedType,
                                     InterceptionType interceptionType,
                                     Class lifeycleAnnotation,
                                     Set> allUsedCdiInterceptors,
                                     Set> allUsedEjbInterceptors,
                                     List> classLevelEjbInterceptors,
                                     Set classInterceptorBindings,
                                     boolean parentFirst)
    {
        List> foundMethods = new ArrayList>();
        BusinessMethodInterceptorInfo methodInterceptorInfo = new BusinessMethodInterceptorInfo();

        List> lifecycleMethodCandidates = webBeansContext.getInterceptorUtil().getLifecycleMethods(annotatedType, lifeycleAnnotation, parentFirst);

        for (AnnotatedMethod lifecycleMethod : lifecycleMethodCandidates)
        {
            verifyLifecycleMethod(lifeycleAnnotation, lifecycleMethod);

            if (lifecycleMethod.getParameters().size() == 0)
            {
                foundMethods.add(lifecycleMethod);
                calculateEjbMethodInterceptors(methodInterceptorInfo, allUsedEjbInterceptors, classLevelEjbInterceptors, lifecycleMethod);

                calculateCdiMethodInterceptors(methodInterceptorInfo, interceptionType, allUsedCdiInterceptors, lifecycleMethod, classInterceptorBindings);
            }
        }

        if (foundMethods.size() > 0 )
        {
            lifecycleMethodInterceptorInfos.put(interceptionType, new LifecycleMethodInfo(foundMethods, methodInterceptorInfo));
        }
    }

    private  void collectEjbInterceptors(List> ejbInterceptors, Annotated annotated, boolean unproxyable, Set types)
    {
        Interceptors interceptorsAnnot = annotated.getAnnotation(Interceptors.class);
        if (interceptorsAnnot != null)
        {
            if (unproxyable)
            {
                throw new WebBeansConfigurationException(annotated + " is not proxyable, but an Interceptor got defined on it!");
            }

            if (types == null)
            {
                types = Collections.emptySet();
            }

            for (Class interceptorClass : interceptorsAnnot.value())
            {
                if (types.contains(interceptorClass)) // don't create another bean for it
                {
                    continue;
                }

                Interceptor ejbInterceptor = webBeansContext.getInterceptorsManager().getEjbInterceptorForClass(interceptorClass);
                ejbInterceptors.add(ejbInterceptor);
            }
        }
    }

    private void calculateEjbMethodInterceptors(BusinessMethodInterceptorInfo methodInterceptorInfo, Set> allUsedEjbInterceptors,
                                                List> classLevelEjbInterceptors, AnnotatedMethod annotatedMethod)
    {
        boolean unproxyable = isUnproxyable(annotatedMethod);

        List> methodInterceptors = new ArrayList>();

        if (classLevelEjbInterceptors != null && classLevelEjbInterceptors.size() > 0 && !unproxyable)
        {
            // add the class level defined Interceptors first

            ExcludeClassInterceptors excludeClassInterceptors = annotatedMethod.getAnnotation(ExcludeClassInterceptors.class);
            if (excludeClassInterceptors == null)
            {
                // but only if there is no exclusion of all class-level interceptors
                methodInterceptors.addAll(classLevelEjbInterceptors);
            }
        }

        collectEjbInterceptors(methodInterceptors, annotatedMethod, unproxyable, Collections.singleton(annotatedMethod.getJavaMember().getDeclaringClass()));
        allUsedEjbInterceptors.addAll(methodInterceptors);

        if (methodInterceptors.size() > 0)
        {
            methodInterceptorInfo.setEjbInterceptors(methodInterceptors);
        }
    }

    private boolean isUnproxyable(AnnotatedMethod annotatedMethod)
    {
        int modifiers = annotatedMethod.getJavaMember().getModifiers();
        return Modifier.isFinal(modifiers) || Modifier.isPrivate(modifiers);
    }


    private void calculateCdiMethodDecorators(BusinessMethodInterceptorInfo methodInterceptorInfo, List> decorators, AnnotatedMethod annotatedMethod)
    {
        if (decorators == null || decorators.isEmpty())
        {
            return;
        }

        LinkedHashMap, Method> appliedDecorators = new LinkedHashMap, Method>();

        for (Decorator decorator : decorators)
        {
            Method decoratingMethod = getDecoratingMethod(decorator, annotatedMethod);
            if (decoratingMethod != null)
            {
                if (isUnproxyable(annotatedMethod))
                {
                    throw new WebBeansConfigurationException(annotatedMethod + " is not proxyable, but an Decorator got defined on it!");
                }

                appliedDecorators.put(decorator, decoratingMethod);
            }
        }

        if (appliedDecorators.size() > 0)
        {
            methodInterceptorInfo.setMethodDecorators(appliedDecorators);
        }
    }

    /**
     * @return the Method from the decorator which decorates the annotatedMethod, null
     *         if the given Decorator does not decorate the annotatedMethod
     */
    private Method getDecoratingMethod(Decorator decorator, AnnotatedMethod annotatedMethod)
    {
        Set decoratedTypes = decorator.getDecoratedTypes();
        for (Type decoratedType : decoratedTypes)
        {
            if (decoratedType instanceof ParameterizedType)
            {
                // TODO handle the case that method parameter types are TypeVariables
                ParameterizedType parameterizedType = (ParameterizedType)decoratedType;
                decoratedType = parameterizedType.getRawType();
            }

            if (decoratedType instanceof Class)
            {
                Class decoratedClass = (Class) decoratedType;
                Method[] decoratorMethods = decoratedClass.getDeclaredMethods();
                for (Method decoratorMethod : decoratorMethods)
                {
                    int modifiers = decoratorMethod.getModifiers();
                    if (Modifier.isFinal(modifiers) ||
                        Modifier.isPrivate(modifiers) ||
                        Modifier.isStatic(modifiers))
                    {
                        continue;
                    }

                    if (methodEquals(decoratorMethod, annotatedMethod.getJavaMember()))
                    {
                        // yikes our method is decorated by this very decorator type.

                        if (Modifier.isAbstract((decorator.getBeanClass().getModifiers())))
                        {
                            // For abstract classes we will only decorate this method if it's really implemented on the decorator itself
                            Class decoratorClass = decorator.getBeanClass();
                            while (decoratorClass != Object.class)
                            {
                                try
                                {
                                    Method m = decoratorClass.getDeclaredMethod(decoratorMethod.getName(), decoratorMethod.getParameterTypes());
                                    if (Modifier.isAbstract(m.getModifiers()))
                                    {
                                        return null;
                                    }
                                    else
                                    {
                                        return decoratorMethod;
                                    }
                                }
                                catch (NoSuchMethodException e)
                                {
                                    // all ok, just continue
                                }

                                decoratorClass = decoratorClass.getSuperclass();
                            }

                            return null;
                        }
                        {
                            return decoratorMethod;
                        }
                    }
                }
            }
        }

        return null;
    }

    private boolean methodEquals(Method method1, Method method2)
    {
        if (method1.getName().equals(method2.getName()))
        {
            Class[] method1Params = method1.getParameterTypes();
            Class[] method2Params = method2.getParameterTypes();
            if (method1Params.length == method2Params.length)
            {
                boolean paramsMatch = true;
                for (int i = 0; i < method1Params.length; i++)
                {
                    if (!method1Params[i].isAssignableFrom(method2Params[i]))
                    {
                        paramsMatch = false;
                        break;
                    }
                }

                if (paramsMatch)
                {
                    return true;
                }
            }
        }

        return false;
    }

    private void calculateCdiMethodInterceptors(BusinessMethodInterceptorInfo methodInterceptorInfo,
                                                InterceptionType interceptionType,
                                                Set> allUsedCdiInterceptors,
                                                AnnotatedMethod annotatedMethod,
                                                Set classInterceptorBindings)
    {
        AnnotationManager annotationManager = webBeansContext.getAnnotationManager();

        boolean unproxyable = isUnproxyable(annotatedMethod);

        Set cummulatedInterceptorBindings = new HashSet();
        cummulatedInterceptorBindings.addAll(
                annotationManager.getInterceptorAnnotations(annotatedMethod.getAnnotations()));

        if (unproxyable && cummulatedInterceptorBindings.size() > 0)
        {
            if (unproxyable)
            {
                throw new WebBeansConfigurationException(annotatedMethod + " is not proxyable, but an Interceptor got defined on it!");
            }
        }

        if (unproxyable)
        {
            // don't apply class level interceptors - instead just return
            return;
        }

        cummulatedInterceptorBindings.addAll(classInterceptorBindings);

        if (cummulatedInterceptorBindings.size() == 0)
        {
            return;
        }

        List> methodInterceptors
                = webBeansContext.getBeanManagerImpl().resolveInterceptors(interceptionType, AnnotationUtil.asArray(cummulatedInterceptorBindings));

        methodInterceptorInfo.setCdiInterceptors(methodInterceptors);

        allUsedCdiInterceptors.addAll(methodInterceptors);
    }

    /**
     * Check that the given lifecycle method has:
     * 
    *
  • either has no parameter at all (standard case), or
  • *
  • has exactly one InvocationContext parameter (self-interception)
  • *
  • has no return value
  • *
* * @param annotatedMethod */ private void verifyLifecycleMethod(Class lifecycleAnnotation, AnnotatedMethod annotatedMethod) { List> params = annotatedMethod.getParameters(); if (params.size() > 0 && (params.size() > 1 || !params.get(0).getBaseType().equals(InvocationContext.class))) { throw new WebBeansConfigurationException(lifecycleAnnotation.getName() + " LifecycleMethod " + annotatedMethod.getJavaMember() + " must either have no parameter or InvocationContext but has:" + Arrays.toString(annotatedMethod.getJavaMember().getParameterTypes())); } if (!annotatedMethod.getJavaMember().getReturnType().equals(Void.TYPE)) { throw new WebBeansConfigurationException("@" + lifecycleAnnotation.getName() + " annotated method : " + annotatedMethod.getJavaMember().getName() + " in class : " + annotatedMethod.getDeclaringType().getJavaClass().getName() + " must return void type"); } if (isNoCheckedExceptionEnforced() && ClassUtil.isMethodHasCheckedException(annotatedMethod.getJavaMember())) { throw new WebBeansConfigurationException("@" + lifecycleAnnotation.getName() + " annotated method : " + annotatedMethod.getJavaMember().getName() + " in class : " + annotatedMethod.getDeclaringType().getJavaClass().getName() + " can not throw any checked exception"); } if (Modifier.isStatic(annotatedMethod.getJavaMember().getModifiers())) { throw new WebBeansConfigurationException("@" + lifecycleAnnotation.getName() + " annotated method : " + annotatedMethod.getJavaMember().getName() + " in class : " + annotatedMethod.getDeclaringType().getJavaClass().getName() + " can not be static"); } } /** * @return the list of all non-overloaded non-private and non-static methods */ private List getInterceptableBusinessMethods(AnnotatedType annotatedType) { List interceptableMethods = ClassUtil.getNonPrivateMethods(annotatedType.getJavaClass(), false); List interceptableAnnotatedMethods = new ArrayList(); Set annotatedMethods = annotatedType.getMethods(); for (Method interceptableMethod : interceptableMethods) { for (AnnotatedMethod annotatedMethod : annotatedMethods) { if (annotatedMethod.getJavaMember().equals(interceptableMethod)) { int modifiers = annotatedMethod.getJavaMember().getModifiers(); if (Modifier.isPrivate(modifiers) || Modifier.isStatic(modifiers)) { // we must only intercept business methods continue; } interceptableAnnotatedMethods.add(annotatedMethod); } } } return interceptableAnnotatedMethods; } /** * static information about interceptors and decorators for a * single bean. */ public static class BeanInterceptorInfo { public BeanInterceptorInfo(List> decorators, LinkedHashSet> ejbInterceptors, List> cdiInterceptors, SelfInterceptorBean selfInterceptorBean, Map businessMethodsInfo, List nonInterceptedMethods, Map lifecycleMethodInterceptorInfos) { this.decorators = decorators; this.ejbInterceptors = ejbInterceptors; this.cdiInterceptors = cdiInterceptors; this.selfInterceptorBean = selfInterceptorBean; this.businessMethodsInfo = businessMethodsInfo; this.nonInterceptedMethods = nonInterceptedMethods; this.lifecycleMethodInterceptorInfos = lifecycleMethodInterceptorInfos; } /** * All the EJB-style Interceptor Beans which are active on this class somewhere. * The Interceptors are sorted according to their definition. */ private LinkedHashSet> ejbInterceptors; /** * All the CDI-style Interceptor Beans which are active on this class somewhere. * This is only used to create the Interceptor instances. * The Interceptors are not sorted according to beans.xml . */ private List> cdiInterceptors; /** * Set if this class intercepts itself. */ private SelfInterceptorBean selfInterceptorBean; /** * All the Decorator Beans active on this class. */ private List> decorators = null; /** * For each business method which is either decorated or intercepted we keep an entry. * If there is no entry then the method has neither a decorator nor an interceptor. */ private Map businessMethodsInfo = new HashMap(); /** * all non-intercepted methods */ private List nonInterceptedMethods = Collections.EMPTY_LIST; /** * Contains info about lifecycle methods. * A method can be a 'business method' when invoked via the user but a * 'lifecycle method' while invoked by the container! */ private Map lifecycleMethodInterceptorInfos = Collections.EMPTY_MAP; public List> getDecorators() { return decorators; } public LinkedHashSet> getEjbInterceptors() { return ejbInterceptors; } public List> getCdiInterceptors() { return cdiInterceptors; } public SelfInterceptorBean getSelfInterceptorBean() { return selfInterceptorBean; } public Map getBusinessMethodsInfo() { return businessMethodsInfo; } public List getNonInterceptedMethods() { return nonInterceptedMethods; } public Map getLifecycleMethodInterceptorInfos() { return lifecycleMethodInterceptorInfos; } } /** * We track per method which Interceptors to invoke */ public static class BusinessMethodInterceptorInfo { private Interceptor[] ejbInterceptors = null; private Interceptor[] cdiInterceptors = null; private LinkedHashMap, Method> methodDecorators = null; public BusinessMethodInterceptorInfo() { } /** * The (sorted) EJB-style ({@link javax.interceptor.Interceptors}) * Interceptor Beans for a specific method or null * if no Interceptor exists for this method. * They must be called before the {@link #cdiInterceptors}! */ public Interceptor[] getEjbInterceptors() { return ejbInterceptors; } /** * The (sorted) CDI Interceptor Beans for a specific method or null * if no Interceptor exists for this method. */ public Interceptor[] getCdiInterceptors() { return cdiInterceptors; } /** * The (sorted) Decorator Beans for a specific method or null * if no Decorator exists for this method. * This Map is sorted! * Key: the Decorator Bean * Value: the decorating method from the decorator instance */ public LinkedHashMap, Method> getMethodDecorators() { return methodDecorators; } public void setCdiInterceptors(List> cdiInterceptors) { if (cdiInterceptors == null || cdiInterceptors.isEmpty()) { this.cdiInterceptors = null; } else { this.cdiInterceptors = cdiInterceptors.toArray(new Interceptor[cdiInterceptors.size()]); } } public void setMethodDecorators(LinkedHashMap, Method> methodDecorators) { if (methodDecorators == null || methodDecorators.isEmpty()) { this.methodDecorators = null; } else { this.methodDecorators = methodDecorators; } } public void setEjbInterceptors(List> ejbInterceptors) { if (ejbInterceptors == null || ejbInterceptors.isEmpty()) { this.ejbInterceptors = null; } else { this.ejbInterceptors = ejbInterceptors.toArray(new Interceptor[ejbInterceptors.size()]); } } /** * Determine if any interceptor information has been set at all. */ public boolean isEmpty() { return cdiInterceptors == null && ejbInterceptors == null && methodDecorators == null; } } public static class LifecycleMethodInfo { private List> methods = new ArrayList>(); private BusinessMethodInterceptorInfo methodInterceptorInfo; public LifecycleMethodInfo(List> methods, BusinessMethodInterceptorInfo methodInterceptorInfo) { this.methods = methods; this.methodInterceptorInfo = methodInterceptorInfo; } public List> getMethods() { return methods; } public BusinessMethodInterceptorInfo getMethodInterceptorInfo() { return methodInterceptorInfo; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy