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

org.apache.webbeans.component.creation.InterceptorBeanBuilder 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.component.creation;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedParameter;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.InterceptionType;
import javax.interceptor.AroundInvoke;
import javax.interceptor.AroundTimeout;
import javax.interceptor.InvocationContext;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.webbeans.component.BeanAttributesImpl;
import org.apache.webbeans.component.InterceptorBean;
import org.apache.webbeans.config.WebBeansContext;
import org.apache.webbeans.exception.WebBeansConfigurationException;
import org.apache.webbeans.intercept.annotation.AroundConstruct;
import org.apache.webbeans.plugins.OpenWebBeansEjbLCAPlugin;
import org.apache.webbeans.util.Asserts;
import org.apache.webbeans.util.ClassUtil;


/**
 * Bean builder for {@link org.apache.webbeans.component.InterceptorBean}s.
 */
public abstract class InterceptorBeanBuilder>
{
    protected final WebBeansContext webBeansContext;
    protected final AnnotatedType annotatedType;
    protected final BeanAttributesImpl beanAttributes;

    private final OpenWebBeansEjbLCAPlugin ejbPlugin;
    private final Class prePassivateClass;
    private final Class postActivateClass;

    private Map interceptionMethods;
    private Method interceptionConstructor = null;

    protected InterceptorBeanBuilder(WebBeansContext webBeansContext, AnnotatedType annotatedType, BeanAttributesImpl beanAttributes)
    {
        Asserts.assertNotNull(webBeansContext, "webBeansContext may not be null");
        Asserts.assertNotNull(annotatedType, "annotated type may not be null");
        Asserts.assertNotNull(beanAttributes, "beanAttributes may not be null");
        this.webBeansContext = webBeansContext;
        this.annotatedType = annotatedType;
        this.beanAttributes = beanAttributes;
        ejbPlugin = webBeansContext.getPluginLoader().getEjbLCAPlugin();
        if (ejbPlugin != null)
        {
            prePassivateClass = ejbPlugin.getPrePassivateClass();
            postActivateClass = ejbPlugin.getPostActivateClass();
        }
        else
        {
            prePassivateClass = null;
            postActivateClass = null;
        }
    }

    /**
     * If this method returns false the {@link #getBean()} method must not get called.
     *
     * @return true if the Interceptor is enabled and a Bean should get created
     */
    public abstract boolean isInterceptorEnabled();

    protected void checkInterceptorConditions()
    {
        Set> methods = annotatedType.getMethods();
        for(AnnotatedMethod method : methods)
        {
            for (AnnotatedParameter parameter : method.getParameters())
            {
                if (parameter.isAnnotationPresent(Produces.class))
                {
                    throw new WebBeansConfigurationException("Interceptor class : " + annotatedType.getJavaClass()
                            + " can not have producer methods but it has one with name : "
                            + method.getJavaMember().getName());
                }
            }
        }
    }

    /**
     * 

Grab all methods which act as interceptors for the various * {@link javax.enterprise.inject.spi.InterceptionType}s.

* *

This method will also check some rules, e.g. that there must not be * more than a single {@link javax.interceptor.AroundInvoke} method * on a class.

* *

For the interceptors where multiple are allowed, the following rules apply: *

    *
  • Superclass methods first
  • *
  • Non-private methods override and derogates their superclass counterparts.
  • *
  • Private methods with the same signature stack (superclass first).
  • *
  • There must only be a single method for each InterceptorType in the same class.
  • *
*

* @return true if we found some interceptor methods */ public boolean defineInterceptorMethods() { List classHierarchy = webBeansContext.getInterceptorUtil().getReverseClassHierarchy(annotatedType.getJavaClass()); Collection aroundInvokeMethod = null; List postConstructMethods = new ArrayList(); List preDestroyMethods = new ArrayList(); List aroundTimeoutMethods = new ArrayList(); // EJB related interceptors List prePassivateMethods = new ArrayList(); List postActivateMethods = new ArrayList(); boolean interceptorFound = false; Set> methods = annotatedType.getMethods(); for (Class clazz : classHierarchy) { for (AnnotatedMethod m : methods) { if (clazz == m.getJavaMember().getDeclaringClass()) { if (m.getAnnotation(AroundConstruct.class) != null) { if (interceptionConstructor != null) { throw new WebBeansConfigurationException("only one AroundConstruct allowed per Interceptor"); } interceptionConstructor = m.getJavaMember(); } // we only take methods from this very class and not sub- or superclasses if (m.getAnnotation(AroundInvoke.class) != null) { if (aroundInvokeMethod != null) { for (final Method ai : aroundInvokeMethod) { if (ai.getDeclaringClass() == m.getJavaMember().getDeclaringClass()) { throw new WebBeansConfigurationException("only one AroundInvoke allowed per Interceptor"); } } } checkAroundInvokeConditions(m); if (aroundInvokeMethod == null) { aroundInvokeMethod = new ArrayList(); } aroundInvokeMethod.add(m.getJavaMember()); } // PostConstruct if (m.getAnnotation(PostConstruct.class) != null) { checkSameClassInterceptors(postConstructMethods, m); postConstructMethods.add(m); // add at last position } // PreDestroy if (m.getAnnotation(PreDestroy.class) != null) { checkSameClassInterceptors(preDestroyMethods, m); preDestroyMethods.add(m); // add at last position } // AroundTimeout if (m.getAnnotation(AroundTimeout.class) != null) { checkSameClassInterceptors(aroundTimeoutMethods, m); aroundTimeoutMethods.add(m); // add at last position } // and now the EJB related interceptors if (ejbPlugin != null) { if (m.getAnnotation(prePassivateClass) != null) { checkSameClassInterceptors(prePassivateMethods, m); prePassivateMethods.add(m); // add at last position } // AroundTimeout if (m.getAnnotation(AroundTimeout.class) != null) { checkSameClassInterceptors(aroundTimeoutMethods, m); postActivateMethods.add(m); // add at last position } // AroundTimeout if (m.getAnnotation(postActivateClass) != null) { checkSameClassInterceptors(postActivateMethods, m); postActivateMethods.add(m); // add at last position } } } } } // and now for setting the bean info interceptionMethods = new HashMap(); if (aroundInvokeMethod != null) { interceptorFound = true; interceptionMethods.put(InterceptionType.AROUND_INVOKE, aroundInvokeMethod.toArray(new Method[aroundInvokeMethod.size()])); } if (postConstructMethods.size() > 0) { interceptorFound = true; interceptionMethods.put(InterceptionType.POST_CONSTRUCT, getMethodArray(postConstructMethods)); } if (preDestroyMethods.size() > 0) { interceptorFound = true; interceptionMethods.put(InterceptionType.PRE_DESTROY, getMethodArray(preDestroyMethods)); } if (aroundTimeoutMethods.size() > 0) { interceptorFound = true; interceptionMethods.put(InterceptionType.AROUND_TIMEOUT, getMethodArray(aroundTimeoutMethods)); } if (prePassivateMethods.size() > 0) { interceptorFound = true; interceptionMethods.put(InterceptionType.PRE_PASSIVATE, getMethodArray(prePassivateMethods)); } if (postActivateMethods.size() > 0) { interceptorFound = true; interceptionMethods.put(InterceptionType.POST_ACTIVATE, getMethodArray(postActivateMethods)); } return interceptorFound; } private void checkAroundInvokeConditions(AnnotatedMethod method) { List> parameters = method.getParameters(); List> clazzParameters = new ArrayList>(); for(AnnotatedParameter parameter : parameters) { clazzParameters.add(ClassUtil.getClazz(parameter.getBaseType())); } Class[] params = clazzParameters.toArray(new Class[clazzParameters.size()]); if (params.length != 1 || !params[0].equals(InvocationContext.class)) { throw new WebBeansConfigurationException("@AroundInvoke annotated method : " + method.getJavaMember().getName() + " in class : " + annotatedType.getJavaClass().getName() + " can not take any formal arguments other than InvocationContext"); } if (!method.getJavaMember().getReturnType().equals(Object.class)) { throw new WebBeansConfigurationException("@AroundInvoke annotated method : " + method.getJavaMember().getName()+ " in class : " + annotatedType.getJavaClass().getName() + " must return Object type"); } if (Modifier.isStatic(method.getJavaMember().getModifiers()) || Modifier.isFinal(method.getJavaMember().getModifiers())) { throw new WebBeansConfigurationException("@AroundInvoke annotated method : " + method.getJavaMember().getName( )+ " in class : " + annotatedType.getJavaClass().getName() + " can not be static or final"); } } /** * @return the a Method array with the native members of the AnnotatedMethod list */ private Method[] getMethodArray(List methodList) { Method[] methods = new Method[methodList.size()]; int i=0; for (AnnotatedMethod am : methodList) { methods[i++] = am.getJavaMember(); } return methods; } private void checkSameClassInterceptors(List alreadyDefinedMethods, AnnotatedMethod annotatedMethod) { Class clazz = null; for (AnnotatedMethod alreadyDefined : alreadyDefinedMethods) { if (clazz == null) { clazz = annotatedMethod.getJavaMember().getDeclaringClass(); } // check for same class -> Exception if (alreadyDefined.getJavaMember().getDeclaringClass() == clazz) { throw new WebBeansConfigurationException("Only one Interceptor of a certain type is allowed per class, but multiple found in class " + annotatedMethod.getJavaMember().getDeclaringClass().getName() + " methods: " + annotatedMethod.getJavaMember().toString() + " and " + alreadyDefined.getJavaMember().toString()); } } } protected abstract B createBean(Class beanClass, boolean enabled, Map interceptionMethods, Method aroundConstruct); public B getBean() { return createBean(annotatedType.getJavaClass(), isInterceptorEnabled(), interceptionMethods, interceptionConstructor); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy