Package org.apache.webbeans.util

Source Code of org.apache.webbeans.util.WebBeansUtil

/*
* 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.util;

import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.decorator.Decorator;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.NormalScope;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.IllegalProductException;
import javax.enterprise.inject.Instance;
import javax.inject.Named;
import javax.inject.Scope;
import javax.enterprise.inject.New;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.UnproxyableResolutionException;
import javax.enterprise.inject.deployment.DeploymentType;
import javax.enterprise.inject.deployment.Specializes;
import javax.enterprise.inject.spi.AnnotatedField;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.enterprise.inject.spi.Interceptor;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.stereotype.Stereotype;
import javax.inject.Inject;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

import org.apache.webbeans.annotation.ApplicationScopeLiteral;
import org.apache.webbeans.annotation.CurrentLiteral;
import org.apache.webbeans.annotation.DependentScopeLiteral;
import org.apache.webbeans.annotation.NewLiteral;
import org.apache.webbeans.annotation.ProductionLiteral;
import org.apache.webbeans.annotation.RequestedScopeLiteral;
import org.apache.webbeans.annotation.StandardLiteral;
import org.apache.webbeans.component.AbstractBean;
import org.apache.webbeans.component.AbstractInjectionTargetBean;
import org.apache.webbeans.component.BaseBean;
import org.apache.webbeans.component.EnterpriseBeanMarker;
import org.apache.webbeans.component.ManagedBean;
import org.apache.webbeans.component.ConversationBean;
import org.apache.webbeans.component.ExtensionBean;
import org.apache.webbeans.component.InjectionPointBean;
import org.apache.webbeans.component.InstanceBean;
import org.apache.webbeans.component.BeanManagerBean;
import org.apache.webbeans.component.NewBean;
import org.apache.webbeans.component.EventBean;
import org.apache.webbeans.component.ProducerMethodBean;
import org.apache.webbeans.component.ProducerFieldBean;
import org.apache.webbeans.component.WebBeansType;
import org.apache.webbeans.config.DefinitionUtil;
import org.apache.webbeans.config.EJBWebBeansConfigurator;
import org.apache.webbeans.config.ManagedBeanConfigurator;
import org.apache.webbeans.container.BeanManagerImpl;
import org.apache.webbeans.conversation.ConversationImpl;
import org.apache.webbeans.decorator.DecoratorUtil;
import org.apache.webbeans.decorator.DecoratorsManager;
import org.apache.webbeans.decorator.WebBeansDecoratorConfig;
import org.apache.webbeans.deployment.DeploymentTypeManager;
import org.apache.webbeans.event.EventImpl;
import org.apache.webbeans.exception.WebBeansConfigurationException;
import org.apache.webbeans.exception.WebBeansException;
import org.apache.webbeans.exception.WebBeansPassivationException;
import org.apache.webbeans.exception.inject.DefinitionException;
import org.apache.webbeans.exception.inject.InconsistentSpecializationException;
import org.apache.webbeans.exception.inject.NullableDependencyException;
import org.apache.webbeans.intercept.InterceptorData;
import org.apache.webbeans.intercept.InterceptorDataImpl;
import org.apache.webbeans.intercept.InterceptorType;
import org.apache.webbeans.intercept.InterceptorUtil;
import org.apache.webbeans.intercept.InterceptorsManager;
import org.apache.webbeans.intercept.WebBeansInterceptorConfig;
import org.apache.webbeans.intercept.webbeans.WebBeansInterceptor;
import org.apache.webbeans.plugins.OpenWebBeansPlugin;
import org.apache.webbeans.plugins.PluginLoader;
import org.apache.webbeans.portable.AnnotatedElementFactory;
import org.apache.webbeans.portable.creation.InjectionTargetProducer;
import org.apache.webbeans.portable.events.generics.GProcessAnnotatedType;
import org.apache.webbeans.portable.events.generics.GProcessInjectionTarget;
import org.apache.webbeans.portable.events.generics.GProcessProducer;
import org.apache.webbeans.portable.events.generics.GProcessProducerField;
import org.apache.webbeans.portable.events.generics.GProcessProducerMethod;

/**
* Contains some utility methods used in the all project.
*
* @version $Rev: 811507 $ $Date: 2009-09-04 21:18:41 +0300 (Fri, 04 Sep 2009) $
*/
@SuppressWarnings("unchecked")
public final class WebBeansUtil
{
    // No instantiate
    private WebBeansUtil()
    {
        throw new UnsupportedOperationException();
    }

    /**
     * Gets current classloader with current thread.
     *
     * @return Current class loader instance
     */
    public static ClassLoader getCurrentClassLoader()
    {
        ClassLoader loader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
        {

            public ClassLoader run()
            {
                try
                {
                    return Thread.currentThread().getContextClassLoader();

                }
                catch (Exception e)
                {
                    return null;
                }
            }

        });

        if (loader == null)
        {
            loader = WebBeansUtil.class.getClassLoader();
        }

        return loader;
    }

    /**
     * Checks the generic type requirements.
     *
     * @param bean managed bean instance
     */
    public static void checkGenericType(Bean<?> bean)
    {
      Asserts.assertNotNull(bean);
     
      Class<?> clazz = bean.getBeanClass();
     
        if (ClassUtil.isDefinitionConstainsTypeVariables(clazz))
        {
            if(!bean.getScope().equals(Dependent.class))
            {
                throw new WebBeansConfigurationException("Generic type may only defined with scope @Dependent for bean class : " + clazz.getName());
            }
        }
    }
   
   
    /**
     * Check producer method/field bean return type.
     * @param bean producer bean instance
     * @param member related member instance
     */
    public static void checkProducerGenericType(Bean<?> bean,Member member)
    {
      Asserts.assertNotNull(bean,"Bean is null");
     
      Type type = null;
     
      if(bean instanceof ProducerMethodBean)
      {
        type = ((ProducerMethodBean<?>)bean).getCreatorMethod().getGenericReturnType();
      }
      else if(bean instanceof ProducerFieldBean)
      {
        type = ((ProducerFieldBean<?>)bean).getCreatorField().getGenericType();
      }
      else
      {
        throw new IllegalArgumentException("Bean must be Producer Field or Method Bean instance : " + bean);
      }
     
      String message = "Producer Field/Method Bean with name : " + member.getName() + " in bean class : " + member.getDeclaringClass().getName();
     
      if(checkGenericForProducers(type, message))
      {
            if(!bean.getScope().equals(Dependent.class))
            {
                throw new WebBeansConfigurationException(message + " scope must bee @Dependent");
            }
      }
    }
   
    /**
     * Check generic types for producer method and fields.
     * @param type generic return type
     * @param message error message
     * @return true if parametrized type argument is TypeVariable
     */
    //Helper method
    private static boolean checkGenericForProducers(Type type, String message)
    {
      boolean result = false;
     
      if(type instanceof TypeVariable)
      {
        throw new WebBeansConfigurationException(message + " return type can not be type variable");
      }
     
      if(ClassUtil.isParametrizedType(type))
      {
        Type[] actualTypes = ClassUtil.getActualTypeArguements(type);
       
        if(actualTypes.length == 0)
        {
            throw new WebBeansConfigurationException(message + " return type must define actual type arguments or type variable");
        }
       
        for(Type actualType : actualTypes)
        {
          if(ClassUtil.isWildCardType(actualType))
          {
            throw new WebBeansConfigurationException(message + " return type can not define wildcard actual type argument");
          }
         
          if(ClassUtil.isTypeVariable(actualType))
          {
            result = true;
          }
        }       
      }
     
      return result;
    }
   
    /**
     * Return <code>true</code> if the given class is ok for manage bean conditions,
     * <code>false</code> otherwise.
     *
     * @param clazz class in hand
     * @return <code>true</code> if the given class is ok for simple web bean conditions.
     */
    public static void isManagedBeanClass(Class<?> clazz)
    {
        Asserts.nullCheckForClass(clazz, "Class is null");
       
        int modifier = clazz.getModifiers();

        if (!ClassUtil.isStatic(modifier) && ClassUtil.isInnerClazz(clazz))
            throw new WebBeansConfigurationException("Bean implementation class : " + clazz.getName() + " can not be non-static inner class");

        if (!ClassUtil.isConcrete(clazz) && !AnnotationUtil.isAnnotationExistOnClass(clazz, Decorator.class))
            throw new WebBeansConfigurationException("Bean implementation class : " + clazz.getName() + " have to be concrete if not defines as @Decorator");
               
        if (!isConstructureOk(clazz))
        {
            throw new WebBeansConfigurationException("Bean implementation class : " + clazz.getName() + " must define at least one Constructor");  
        }
           
        // and finally call all checks which are defined in plugins like JSF, JPA, etc
        List<OpenWebBeansPlugin> plugins = PluginLoader.getInstance().getPlugins();
        for (OpenWebBeansPlugin plugin : plugins)
        {
            plugin.isManagedBean(clazz);
        }
    }

    /**
     * Defines applicable constructor.
     * @param <T> type info
     * @param clazz class type
     * @return constructor
     * @throws WebBeansConfigurationException any configuration exception
     */
    public static <T> Constructor<T> defineConstructor(Class<T> clazz) throws WebBeansConfigurationException
    {
        Asserts.nullCheckForClass(clazz);
        Constructor<T> result = null;
        Constructor<T>[] constructors = ClassUtil.getConstructors(clazz);

        boolean inAnnotation = false;
        int j = 0;

        /* Check for @Initializer */
        for (Constructor<T> constructor : constructors)
        {
            j++;
            if (constructor.getAnnotation(Inject.class) != null)
            {
                if (inAnnotation == true)// duplicate @In
                {
                    throw new WebBeansConfigurationException("There are more than one Constructor with Initializer annotation in class " + clazz.getName());
                }
                else
                {
                    inAnnotation = true;
                    result = constructor;
                }
            }
        }

        if (result != null)
        {
            Annotation[][] parameterAnns = result.getParameterAnnotations();
            for (Annotation[] parameters : parameterAnns)
            {
                for (Annotation param : parameters)
                {
                    Annotation btype = param.annotationType().getAnnotation(Disposes.class);
                    if (btype != null)
                    {
                        throw new WebBeansConfigurationException("Constructor parameter qualifier annotation can not be @Disposes annotation in class " + clazz.getName());
                    }
                    else
                    {
                        btype = param.annotationType().getAnnotation(Observes.class);
                        if (btype != null)
                        {
                            throw new WebBeansConfigurationException("Constructor parameter qualifier annotation can not be @Observes annotation in class " + clazz.getName());
                        }
                    }
                }

            }
        }

        if (result == null)
        {
            if ((result = ClassUtil.isContaintNoArgConstructor(clazz)) != null)
            {
                return result;
            }
            else
            {
                throw new WebBeansConfigurationException("No constructor is found for the class : " + clazz.getName());
            }
        }

        return result;
    }

    /**
     * Check that simple web beans class has compatible constructor.
     * @param clazz web beans simple class
     * @throws WebBeansConfigurationException if the web beans has incompatible
     *             constructor
     */
    public static boolean isConstructureOk(Class<?> clazz) throws WebBeansConfigurationException
    {
        Asserts.nullCheckForClass(clazz);

        if (ClassUtil.isContaintNoArgConstructor(clazz) != null)
        {
            return true;
        }

        Constructor<?>[] constructors = ClassUtil.getConstructors(clazz);

        int j = 0;

        for (Constructor<?> constructor : constructors)
        {
            j++;
            if (constructor.getAnnotation(Inject.class) != null)
            {
                return true;
            }
        }

        return false;
    }
   
    /**
     * Check producer method is ok for deployment.
     *
     * @param method producer method
     * @param parentImplClazzName parent class name
     */
    public static void checkProducerMethodForDeployment(Method method, String parentImplClazzName)
    {
        Asserts.assertNotNull(method, "Method argument can not be null");

        if (AnnotationUtil.isMethodHasAnnotation(method, Inject.class) || AnnotationUtil.isMethodParameterAnnotationExist(method, Disposes.class) || AnnotationUtil.isMethodParameterAnnotationExist(method, Observes.class))
        {
            throw new WebBeansConfigurationException("Producer Method Bean with name : " + method.getName() + " in bean class : " + parentImplClazzName + " can not be annotated with" + " @Initializer/@Destructor annotation or has a parameter annotated with @Disposes/@Observes");
        }
    }
   
    /**
     * CheckProducerMethodDisposal.
     * @param disposalMethod disposal method
     * @param definedBeanClassName bean class name
     */
    public static void checkProducerMethodDisposal(Method disposalMethod, String definedBeanClassName)
    {
        if (AnnotationUtil.isMethodMultipleParameterAnnotationExist(disposalMethod, Disposes.class))
        {
            throw new WebBeansConfigurationException("Disposal method : " + disposalMethod.getName() + " in class " + definedBeanClassName + " has multiple @Disposes annotation parameter");
        }

        if (AnnotationUtil.isMethodHasAnnotation(disposalMethod, Inject.class) || AnnotationUtil.isMethodParameterAnnotationExist(disposalMethod, Observes.class) || AnnotationUtil.isMethodHasAnnotation(disposalMethod, Produces.class))
        {
            throw new WebBeansConfigurationException("Disposal method : " + disposalMethod.getName() + " in the class : " + definedBeanClassName + " can not be annotated with" + " @Initializer/@Destructor/@Produces annotation or has a parameter annotated with @Observes");
        }

    }

    /**
     * Check conditions for the new binding.
     * @param annotations annotations
     * @return Annotation[] with all binding annotations
     * @throws WebBeansConfigurationException if &x0040;New plus any other binding annotation is set or
     *         if &x0040;New is used for an Interface or an abstract class.
     */
    public static Annotation[] checkForNewQualifierForDeployment(Type type, Class<?> clazz, String name, Annotation[] annotations)
    {
        Asserts.assertNotNull(type, "Type argument can not be null");
        Asserts.assertNotNull(clazz, "Clazz argument can not be null");
        Asserts.assertNotNull(annotations, "Annotations argument can not be null");

        Annotation[] as = AnnotationUtil.getQualifierAnnotations(annotations);
        for (Annotation a : annotations)
        {
            if (a.annotationType().equals(New.class))
            {
                if (as.length > 1)
                {
                    throw new WebBeansConfigurationException("@New binding annotation can not have any binding annotation in class : " + clazz.getName() + " in field/method : " + name);
                }

                if (ClassUtil.isAbstract(ClassUtil.getClass(type).getModifiers()) || ClassUtil.isInterface(ClassUtil.getClass(type).getModifiers()))
                {
                    throw new WebBeansConfigurationException("@New binding annotation field can not have interface or abstract type in class : " + clazz.getName() + " in field/method : " + name);
                }
            }
        }
       
        return as;
    }

    /**
     * Check conditions for the resources.
     *
     * @param annotations annotations
     * @throws WebBeansConfigurationException if resource annotations exists and do not fit to the fields type, etc.
     * @see AnnotationUtil#isResourceAnnotation(Class)
     */
    public static void checkForValidResources(Type type, Class<?> clazz, String name, Annotation[] annotations)
    {
        Asserts.assertNotNull(type, "Type argument can not be null");
        Asserts.assertNotNull(clazz, "Clazz argument can not be null");
        Asserts.assertNotNull(annotations, "Annotations argument can not be null");

        List<OpenWebBeansPlugin> plugins = PluginLoader.getInstance().getPlugins();
        for (OpenWebBeansPlugin plugin : plugins)
        {
            plugin.checkForValidResources(type, clazz, name, annotations);
        }
    }
   
    /**
     * Returns true if src scope encloses the target.
     *
     * @param src src scope
     * @param target target scope
     * @return true if src scope encloses the target
     */
    public static boolean isScopeEncloseOther(Class<? extends Annotation> src, Class<? extends Annotation> target)
    {
        Asserts.assertNotNull(src, "Src argument can not be null");
        Asserts.assertNotNull(target, "Target argument can not be null");

        if (src.equals(ConversationScoped.class))
        {
            return true;
        }
        else if (src.equals(ApplicationScoped.class))
        {
            if (target.equals(ConversationScoped.class) || (target.equals(ApplicationScoped.class)))
            {
                return false;
            }
            else
            {
                return true;
            }

        }
        else if (src.equals(SessionScoped.class))
        {
            if (target.equals(ConversationScoped.class) || target.equals(ApplicationScoped.class) || target.equals(SessionScoped.class))
            {
                return false;
            }
            else
            {
                return true;
            }

        }
        else if (src.equals(RequestScoped.class))
        {
            return false;
        }
        else
        {
            throw new WebBeansException("Scope is not correct");
        }

    }

    /**
     * New WebBeans component class.
     *
     * @param <T>
     * @param clazz impl. class
     * @return the new component
     */
    public static <T> NewBean<T> createNewComponent(Class<T> clazz)
    {
        Asserts.assertNotNull(clazz, "Clazz argument can not be null");

        NewBean<T> comp = null;

        if (ManagedBeanConfigurator.isManagedBean(clazz))
        {
            comp = new NewBean<T>(clazz, WebBeansType.MANAGED);
            comp.setConstructor(WebBeansUtil.defineConstructor(clazz));

            DefinitionUtil.defineInjectedFields(comp);
            DefinitionUtil.defineInjectedMethods(comp);
        }
        else if (EJBWebBeansConfigurator.isSessionBean(clazz))
        {
            comp = new NewBean<T>(clazz, WebBeansType.ENTERPRISE);
        }
        else
        {
            throw new WebBeansConfigurationException("@New annotation on type : " + clazz.getName() + " must defined as a simple or an enterprise web bean");
        }

        comp.setImplScopeType(new DependentScopeLiteral());
        comp.addQualifier(new NewLiteral());
        comp.setName(null);
        comp.addApiType(clazz);
        comp.addApiType(Object.class);
        comp.setType(new ProductionLiteral());

        return comp;
    }
   
    /**
     * Creates a new extension bean.
     *
     * @param <T> extension service class
     * @param clazz impl. class
     * @return a new extension service bean
     */
    public static <T> ExtensionBean<T> createExtensionComponent(Class<T> clazz)
    {
        Asserts.assertNotNull(clazz, "Clazz argument can not be null");

        ExtensionBean<T> comp = null;
        comp = new ExtensionBean<T>(clazz);
       
        DefinitionUtil.defineApiTypes(comp, clazz);
       
        comp.setImplScopeType(new ApplicationScopeLiteral());
        comp.addQualifier(new CurrentLiteral());
        comp.setType(new ProductionLiteral());
       
        DefinitionUtil.defineObserverMethods(comp, clazz);

        return comp;
    }
   

    /**
     * Returns a new managed bean from given bean.
     *
     * @param <T> bean type parameter
     * @param component managed bean
     * @return the new bean from given managed bean
     */
    public static <T> NewBean<T> createNewSimpleBeanComponent(ManagedBean<T> component)
    {
        Asserts.assertNotNull(component, "component argument can not be null");

        NewBean<T> comp = null;

        comp = new NewBean<T>(component.getReturnType(), WebBeansType.NEW);
       
        DefinitionUtil.defineApiTypes(comp, component.getReturnType());
        comp.setConstructor(component.getConstructor());
       
        for(Field injectedField : component.getInjectedFields())
        {
            comp.addInjectedField(injectedField);
        }
       
        for(Method injectedMethod : component.getInjectedMethods())
        {
            comp.addInjectedMethod(injectedMethod);
        }
       
        List<InterceptorData> interceptorList = component.getInterceptorStack();
        if(!interceptorList.isEmpty())
        {
            component.getInterceptorStack().addAll(interceptorList);  
        }
       
       
        comp.setImplScopeType(new DependentScopeLiteral());
        comp.addQualifier(new NewLiteral());
        comp.setType(new StandardLiteral());
        comp.setName(null);
       
        Set<InjectionPoint> injectionPoints = component.getInjectionPoints();
        for(InjectionPoint injectionPoint : injectionPoints)
        {
            comp.addInjectionPoint(injectionPoint);
        }       

        return comp;
    }   
   
    /**
     * Creates a new event bean instance.
     * @param <T> type info
     * @param returnType bean api type
     * @param eventType event type
     * @param annotations event binding annotations
     * @return new event bean instance
     */
    public static <T> EventBean<T> createObservableImplicitComponent(Class<T> returnType, Type eventType, Annotation... annotations)
    {
        EventBean<T> component = new EventBean<T>(returnType, eventType, WebBeansType.OBSERVABLE);

        DefinitionUtil.defineApiTypes(component, returnType);
        DefinitionUtil.defineQualifiers(component, annotations);

        component.setType(new StandardLiteral());
        component.setImplScopeType(new DependentScopeLiteral());                     

        return component;
    }

    /**
     * Creates a new manager bean instance.
     * @return new manager bean instance
     */
    public static BeanManagerBean getManagerComponent()
    {
        BeanManagerBean managerComponent = new BeanManagerBean();

        managerComponent.setImplScopeType(new DependentScopeLiteral());
        managerComponent.setType(new StandardLiteral());
        managerComponent.addQualifier(new CurrentLiteral());
        managerComponent.addApiType(BeanManager.class);
        managerComponent.addApiType(Object.class);

        return managerComponent;
    }
   
    /**
     * Creates a new instance bean.
     * @param <T> type info
     * @param instance Instance instance
     * @param clazz Instance class
     * @param injectedType injected type
     * @param obtainsBindings instance bindings
     * @return new instance bean
     */
    public static <T> InstanceBean<T> createInstanceComponent(ParameterizedType instance,Class<Instance<T>> clazz, Type injectedType, Annotation...obtainsBindings)
    {
        InstanceBean<T> instanceComponent = new InstanceBean<T>(clazz,injectedType);
       
        instanceComponent.addApiType(clazz);
        instanceComponent.addApiType(Object.class);
       
        DefinitionUtil.defineQualifiers(instanceComponent, obtainsBindings);
        instanceComponent.setImplScopeType(new DependentScopeLiteral());
        instanceComponent.setType(new StandardLiteral());
        instanceComponent.setName(null);
       
       
        return instanceComponent;
    }

    /**
     * Returns new conversation bean instance.
     * @return new conversation bean
     */
    public static ConversationBean getConversationComponent()
    {
        ConversationBean conversationComp = new ConversationBean();

        conversationComp.addApiType(Conversation.class);
        conversationComp.addApiType(ConversationImpl.class);
        conversationComp.addApiType(Object.class);
        conversationComp.setImplScopeType(new RequestedScopeLiteral());
        conversationComp.setType(new StandardLiteral());
        conversationComp.addQualifier(new CurrentLiteral());
        conversationComp.setName("javax.context.conversation");

        return conversationComp;
    }
   
    /**
     * Returns a new injected point bean instance.
     * @return new injected point bean
     */
    public static InjectionPointBean getInjectionPointComponent()
    {
        return new InjectionPointBean(null);
    }

    /**
     * Check the {@link PostConstruct} or {@link PreDestroy} annotated method
     * criterias, and return post construct or pre destroy method.
     * <p>
     * Web Beans container is responsible for setting the post construct or pre
     * destroy annotation if the web beans component is not an EJB components,
     * in this case EJB container is responsible for this.
     * </p>
     *
     * @param clazz checked class
     * @param commonAnnotation post construct or predestroy annotation
     * @return post construct or predestroy method
     */
    public static Method checkCommonAnnotationCriterias(Class<?> clazz, Class<? extends Annotation> commonAnnotation, boolean invocationContext)
    {
        Asserts.assertNotNull(clazz, "Clazz argument can not be null");

        Method[] methods = ClassUtil.getDeclaredMethods(clazz);
        Method result = null;
        boolean found = false;
        for (Method method : methods)
        {
            if (AnnotationUtil.isMethodHasAnnotation(method, commonAnnotation))
            {
                if (ClassUtil.isMoreThanOneMethodWithName(method.getName(), clazz))
                {
                    continue;
                }

                if (found == true)
                {
                    throw new WebBeansConfigurationException("@" + commonAnnotation.getSimpleName() + " annotation is declared more than one method in the class : " + clazz.getName());
                }
                else
                {
                    found = true;
                    result = method;

                    // Check method criterias
                    if (ClassUtil.isMethodHasParameter(method))
                    {
                        if (!invocationContext)
                            throw new WebBeansConfigurationException("@" + commonAnnotation.getSimpleName() + " annotated method : " + method.getName() + " in class : " + clazz.getName() + " can not take any formal arguments");
                        else
                        {
                            // Check method criterias
                            Class<?>[] params = ClassUtil.getMethodParameterTypes(method);
                            if (params.length != 1 || !params[0].equals(InvocationContext.class))
                                throw new WebBeansConfigurationException("@" + commonAnnotation.getSimpleName() + " annotated method : " + method.getName() + " in class : " + clazz.getName() + " can not take any formal arguments other than InvocationContext");

                        }
                    }

                    if (!ClassUtil.getReturnType(method).equals(Void.TYPE))
                    {
                        throw new WebBeansConfigurationException("@" + commonAnnotation.getSimpleName() + " annotated method : " + method.getName() + " in class : " + clazz.getName() + " must return void type");
                    }

                    if (ClassUtil.isMethodHasCheckedException(method))
                    {
                        throw new WebBeansConfigurationException("@" + commonAnnotation.getSimpleName() + " annotated method : " + method.getName() + " in class : " + clazz.getName() + " can not throw any checked exception");
                    }

                    if (ClassUtil.isStatic(method.getModifiers()))
                    {
                        throw new WebBeansConfigurationException("@" + commonAnnotation.getSimpleName() + " annotated method : " + method.getName() + " in class : " + clazz.getName() + " can not be static");
                    }
                }
            }
        }

        return result;
    }

    /**
     * Check the {@link AroundInvoke} annotated method criterias, and return
     * around invoke method.
     * <p>
     * Web Beans container is responsible for setting around invoke annotation
     * if the web beans component is not an EJB components, in this case EJB
     * container is responsible for this.
     * </p>
     *
     * @param clazz checked class
     * @return around invoke method
     */
    public static Method checkAroundInvokeAnnotationCriterias(Class<?> clazz)
    {
        Asserts.assertNotNull(clazz, "Clazz argument can not be null");

        Method[] methods = ClassUtil.getDeclaredMethods(clazz);
        Method result = null;
        boolean found = false;
        for (Method method : methods)
        {
            if (AnnotationUtil.isMethodHasAnnotation(method, AroundInvoke.class))
            {
                // Overriden methods
                if (ClassUtil.isMoreThanOneMethodWithName(method.getName(), clazz))
                {
                    continue;
                }

                if (found == true)
                {
                    throw new WebBeansConfigurationException("@" + AroundInvoke.class.getSimpleName() + " annotation is declared more than one method in the class : " + clazz.getName());
                }
                else
                {
                    found = true;
                    result = method;

                    // Check method criterias
                    Class<?>[] params = ClassUtil.getMethodParameterTypes(method);
                    if (params.length != 1 || !params[0].equals(InvocationContext.class))
                        throw new WebBeansConfigurationException("@" + AroundInvoke.class.getSimpleName() + " annotated method : " + method.getName() + " in class : " + clazz.getName() + " can not take any formal arguments other than InvocationContext");

                    if (!ClassUtil.getReturnType(method).equals(Object.class))
                    {
                        throw new WebBeansConfigurationException("@" + AroundInvoke.class.getSimpleName() + " annotated method : " + method.getName() + " in class : " + clazz.getName() + " must return Object type");
                    }

                    if (!ClassUtil.isMethodHasException(method))
                    {
                        throw new WebBeansConfigurationException("@" + AroundInvoke.class.getSimpleName() + " annotated method : " + method.getName() + " in class : " + clazz.getName() + " must throw Exception");
                    }

                    if (ClassUtil.isStatic(method.getModifiers()) || ClassUtil.isFinal(method.getModifiers()))
                    {
                        throw new WebBeansConfigurationException("@" + AroundInvoke.class.getSimpleName() + " annotated method : " + method.getName() + " in class : " + clazz.getName() + " can not be static or final");
                    }
                }
            }
        }

        return result;
    }

    /**
     * Configures the interceptor stack of the web beans component.
     *
     * @param clazz interceptor class
     * @param annotation annotation type
     * @param definedInInterceptorClass check if annotation is defined in
     *            interceptor class
     * @param definedInMethod check if the interceptor is defined in the comp.
     *            method
     * @param stack interceptor stack
     * @param annotatedInterceptorClassMethod if definedInMethod, this specify
     *            method
     * @param isDefinedWithWebBeans if interceptor is defined with WebBeans
     *            spec, not EJB spec
     */
    public static void configureInterceptorMethods(Interceptor<?> webBeansInterceptor, Class<?> clazz, Class<? extends Annotation> annotation, boolean definedInInterceptorClass, boolean definedInMethod, List<InterceptorData> stack, Method annotatedInterceptorClassMethod, boolean isDefinedWithWebBeans)
    {
        InterceptorData intData = null;
        Method method = null;

        if (annotation.equals(AroundInvoke.class))
        {
            method = WebBeansUtil.checkAroundInvokeAnnotationCriterias(clazz);
        }
        else if (annotation.equals(PostConstruct.class))
        {
            if (definedInInterceptorClass)
            {
                method = WebBeansUtil.checkCommonAnnotationCriterias(clazz, PostConstruct.class, true);
            }
            else
            {
                method = WebBeansUtil.checkCommonAnnotationCriterias(clazz, PostConstruct.class, false);
            }
        }
        else if (annotation.equals(PreDestroy.class))
        {
            if (definedInInterceptorClass)
            {
                method = WebBeansUtil.checkCommonAnnotationCriterias(clazz, PreDestroy.class, true);
            }
            else
            {
                method = WebBeansUtil.checkCommonAnnotationCriterias(clazz, PreDestroy.class, false);
            }
        }

        if (method != null)
        {
            intData = new InterceptorDataImpl(isDefinedWithWebBeans);
            intData.setDefinedInInterceptorClass(definedInInterceptorClass);
            intData.setDefinedInMethod(definedInMethod);
            intData.setAnnotatedMethod(annotatedInterceptorClassMethod);
            intData.setWebBeansInterceptor(webBeansInterceptor);

            if (definedInInterceptorClass)
            {
                try
                {
                    if (isDefinedWithWebBeans)
                    {
                        Object interceptorProxy = BeanManagerImpl.getManager().getInstance(webBeansInterceptor);
                        WebBeansInterceptor<?> interceptor = (WebBeansInterceptor<?>) webBeansInterceptor;
                        interceptor.setInjections(interceptorProxy);

                        //Setting interceptor proxy instance
                        intData.setInterceptorInstance(interceptorProxy);
                    }
                    else
                    {
                        if (ClassUtil.isContaintNoArgConstructor(clazz) == null)
                        {
                            throw new WebBeansConfigurationException("Interceptor class : " + clazz.getName() + " must have no-arg constructor");
                        }

                        intData.setInterceptorInstance(clazz.newInstance());
                    }

                }
                catch (WebBeansConfigurationException e1)
                {
                    throw e1;
                }
                catch (Exception e)
                {
                    throw new WebBeansException(e);
                }
            }

            intData.setInterceptor(method, annotation);

            stack.add(intData);
        }
    }

    /**
     * Returns true if interceptor stack contains interceptor with given type.
     *
     * @param stack interceptor stack
     * @param type interceptor type
     * @return true if stack contains the interceptor with given type
     */
    public static boolean isContainsInterceptorMethod(List<InterceptorData> stack, InterceptorType type)
    {
        Iterator<InterceptorData> it = stack.iterator();
        while (it.hasNext())
        {
            Method m = null;
            InterceptorData data = it.next();

            if (type.equals(InterceptorType.AROUND_INVOKE))
            {
                m = data.getAroundInvoke();
            }
            else if (type.equals(InterceptorType.POST_CONSTRUCT))
            {
                m = data.getPostConstruct();

            }
            else if (type.equals(InterceptorType.PRE_DESTROY))
            {
                m = data.getPreDestroy();
            }

            if (m != null)
            {
                return true;
            }

        }

        return false;
    }

    /**
     * Gets list of interceptors with the given type.
     *
     * @param stack interceptor stack
     * @param type interceptor type
     * @return list of interceptor
     */
   
    public static List<InterceptorData> getInterceptorMethods(List<InterceptorData> stack, InterceptorType type)
    {
        List<InterceptorData> ai = new ArrayList<InterceptorData>();
        List<InterceptorData> pc = new ArrayList<InterceptorData>();
        List<InterceptorData> pd = new ArrayList<InterceptorData>();

        Iterator<InterceptorData> it = stack.iterator();
        while (it.hasNext())
        {
            Method m = null;
            InterceptorData data = it.next();

            if (type.equals(InterceptorType.AROUND_INVOKE))
            {
                m = data.getAroundInvoke();
                if (m != null)
                {
                    ai.add(data);
                }

            }
            else if (type.equals(InterceptorType.POST_CONSTRUCT))
            {
                m = data.getPostConstruct();
                if (m != null)
                {
                    pc.add(data);
                }

            }
            else if (type.equals(InterceptorType.PRE_DESTROY))
            {
                m = data.getPreDestroy();
                if (m != null)
                {
                    pd.add(data);
                }

            }

        }

        if (type.equals(InterceptorType.AROUND_INVOKE))
        {
            return ai;
        }
        else if (type.equals(InterceptorType.POST_CONSTRUCT))
        {
            return pc;

        }
        else if (type.equals(InterceptorType.PRE_DESTROY))
        {
            return pd;
        }

        return Collections.EMPTY_LIST;
    }

    /**
     * Returns true if array contains the StereoType meta annotation
     *
     * @param anns annotation array
     * @return true if array contains the StereoType meta annotation
     */
    public static boolean isComponentHasStereoType(BaseBean<?> component)
    {
        Asserts.assertNotNull(component, "component parameter can not be null");

        Set<Annotation> set = component.getOwbStereotypes();
        Annotation[] anns = new Annotation[set.size()];
        anns = set.toArray(anns);
        if (AnnotationUtil.isStereoTypeMetaAnnotationExist(anns))
        {
            return true;
        }

        return false;
    }

    /**
     * Returns bean stereotypes.
     * @param bean bean instance
     * @return bean stereotypes
     */
    public static Annotation[] getComponentStereoTypes(BaseBean<?> bean)
    {
        Asserts.assertNotNull(bean, "bean parameter can not be null");
        if (isComponentHasStereoType(bean))
        {
            Set<Annotation> set = bean.getOwbStereotypes();
            Annotation[] anns = new Annotation[set.size()];
            anns = set.toArray(anns);

            return AnnotationUtil.getStereotypeMetaAnnotations(anns);
        }

        return new Annotation[] {};
    }

    /**
     * Returns true if name exists,false otherwise.
     * @param bean bean instance
     * @return true if name exists
     */
    public static boolean isNamedExistOnStereoTypes(BaseBean<?> bean)
    {
        Annotation[] types = getComponentStereoTypes(bean);

        for (Annotation ann : types)
        {
            if (AnnotationUtil.isAnnotationExistOnClass(ann.annotationType(), Named.class))
            {
                return true;
            }
        }

        return false;
    }

    public static Annotation getMaxPrecedenceSteroTypeDeploymentType(BaseBean<?> component)
    {
        Annotation[] deploymentTypes = getComponentStereoTypes(component);
        Class<? extends Annotation> maxPrecedDeploymentType = null;
        Annotation result = null;
        if (deploymentTypes.length > 0)
        {
            for (Annotation dt : deploymentTypes)
            {
                if (AnnotationUtil.isMetaAnnotationExist(dt.annotationType().getDeclaredAnnotations(), DeploymentType.class))
                {
                    Annotation result2[] = AnnotationUtil.getMetaAnnotations(dt.annotationType().getDeclaredAnnotations(), DeploymentType.class);

                    Class<? extends Annotation> dtAnnot = result2[0].annotationType();
                    if (maxPrecedDeploymentType == null)
                    {
                        maxPrecedDeploymentType = dtAnnot;
                        result = result2[0];
                    }
                    else
                    {
                        if (DeploymentTypeManager.getInstance().comparePrecedences(maxPrecedDeploymentType, dtAnnot) < 0)
                        {
                            maxPrecedDeploymentType = dtAnnot;
                            result = result2[0];
                        }
                    }
                }

            }
        }

        return result;
    }

    public static String getSimpleWebBeanDefaultName(String clazzName)
    {
        Asserts.assertNotNull(clazzName);
       
        if(clazzName.length() > 0)
        {
            StringBuffer name = new StringBuffer(clazzName);
            name.setCharAt(0, Character.toLowerCase(name.charAt(0)));

            return name.toString();           
        }
       
        return clazzName;
    }

    public static String getProducerDefaultName(String methodName)
    {
        StringBuffer buffer = new StringBuffer(methodName);
           
        if (buffer.length() > 3 &&  (buffer.substring(0, 3).equals("get") || buffer.substring(0, 3).equals("set")))               
        {
           
            if(Character.isUpperCase(buffer.charAt(3)))
            {
                buffer.setCharAt(3, Character.toLowerCase(buffer.charAt(3)));  
            }

            return buffer.substring(3);
        }
        else if ((buffer.length() > 2 &&  buffer.substring(0, 2).equals("is")))               
        {           
            if(Character.isUpperCase(buffer.charAt(2)))
            {
                buffer.setCharAt(2, Character.toLowerCase(buffer.charAt(2)));  
            }

            return buffer.substring(2);
        }
       
        else
        {
            buffer.setCharAt(0, Character.toLowerCase(buffer.charAt(0)));
            return buffer.toString();
        }
    }

    /**
     * Validates that given class obeys stereotype model
     * defined by the specification.
     * @param clazz stereotype class
     */
    public static void checkStereoTypeClass(Class<?> clazz)
    {
        Asserts.nullCheckForClass(clazz);

        Annotation[] annotations = clazz.getDeclaredAnnotations();

        boolean deploymentTypeFound = false;
        boolean scopeTypeFound = false;
        for (Annotation annotation : annotations)
        {
            Class<? extends Annotation> annotType = annotation.annotationType();

            if (annotType.isAnnotationPresent(DeploymentType.class))
            {
                if (deploymentTypeFound == true)
                {
                    throw new WebBeansConfigurationException("@StereoType annotation can not contain more than one @DeploymentType annotation");
                }
                else
                {
                    deploymentTypeFound = true;
                }
            }
            else if (annotType.isAnnotationPresent(NormalScope.class) || annotType.isAnnotationPresent(Scope.class))
            {
                if (scopeTypeFound == true)
                {
                    throw new WebBeansConfigurationException("@StereoType annotation can not contain more than one @Scope/@NormalScope annotation");
                }
                else
                {
                    scopeTypeFound = true;
                }
            }
            else if (annotType.equals(Named.class))
            {
                Named name = (Named) annotation;
                if (!name.value().equals(""))
                {
                    throw new WebBeansConfigurationException("@StereoType annotation can not define @Named annotation with value");
                }
            }
            else if (AnnotationUtil.isQualifierAnnotation(annotType))
            {
                throw new WebBeansConfigurationException("@StereoType annotation can not define @Qualifier annotation");
            }
            else if (AnnotationUtil.isInterceptorBindingAnnotation(annotType))
            {
                Target target = clazz.getAnnotation(Target.class);
                ElementType[] type = target.value();

                if (type.length != 1 && !type[0].equals(ElementType.TYPE))
                {
                    throw new WebBeansConfigurationException("Stereotype with @InterceptorBinding must be defined as @Target{TYPE}");
                }

            }
        }
    }

    /**
     * Configures the bean specializations.
     * <p>
     * Specialized beans inherit the <code>name</code> property
     * from their parents. Specialized bean deployment priority
     * must be higher than its super class related bean.
     * </p>
     *
     * @param specializedClass specialized class
     * @throws DefinitionException if name is defined
     * @throws InconsistentSpecializationException related with priority
     * @throws WebBeansConfigurationException any other exception
     */
    public static void configureSpecializations(Class<?> specializedClass)
    {
        Asserts.nullCheckForClass(specializedClass);

        Bean<?> superBean = null;
        Bean<?> specialized = null;
        Set<Bean<?>> resolvers = null;
       
        if ((resolvers = isConfiguredWebBeans(specializedClass,true)) != null)
        {           
            if(resolvers.isEmpty())
            {
                throw new InconsistentSpecializationException("Specialized bean for class : " + specializedClass + " is not enabled in the deployment.");
            }
           
            if(resolvers.size() > 1)
            {
                throw new InconsistentSpecializationException("More than one specialized bean for class : " + specializedClass + " is enabled in the deployment.");
            }
           
                                  
            specialized = resolvers.iterator().next();
           
            Class<?> superClass = specializedClass.getSuperclass();
           
            resolvers = isConfiguredWebBeans(superClass,false);
           
            for(Bean<?> candidates : resolvers)
            {
                AbstractBean<?> candidate = (AbstractBean<?>)candidates;
               
                if(!(candidate instanceof NewBean))
                {
                    if(candidate.getReturnType().equals(superClass))
                    {
                        superBean = candidates;
                        break;
                    }                   
                }               
            }
                       
            if (superBean != null)
            {
                int res = DeploymentTypeManager.getInstance().comparePrecedences(specialized.getDeploymentType(), superBean.getDeploymentType());
                if (res <= 0)
                {
                    throw new InconsistentSpecializationException("@Specializes exception. Class : " + specializedClass.getName() + " must have higher deployment type precedence from the class : " + superClass.getName());
                }
               
                AbstractBean<?> comp = (AbstractBean<?>)specialized;

                if(superBean.getName() != null)
                {
                    if(comp.getName() != null)
                    {
                        throw new DefinitionException("@Specialized Class : " + specializedClass.getName() + " may not explicitly declare a bean name");
                    }                   
                   
                    comp.setName(superBean.getName());
                    comp.setSpecializedBean(true);
                }
                               
                specialized.getQualifiers().addAll(superBean.getQualifiers());
            }
           
            else
            {
                throw new InconsistentSpecializationException("WebBean component class : " + specializedClass.getName() + " is not enabled for specialized by the " + specializedClass + " class");
            }
        }

    }

    public static Set<Bean<?>> isConfiguredWebBeans(Class<?> clazz,boolean annotate)
    {  
        Asserts.nullCheckForClass(clazz);
       
        Set<Bean<?>> beans = new HashSet<Bean<?>>();
       
        Set<Bean<?>> components = BeanManagerImpl.getManager().getComponents();
        Iterator<Bean<?>> it = components.iterator();

        while (it.hasNext())
        {
            AbstractBean<?> bean = (AbstractBean<?>)it.next();
           
            if (bean.getTypes().contains(clazz))
            {
                if(annotate)
                {
                    if(bean.getReturnType().isAnnotationPresent(Specializes.class))
                    {
                        if(!(bean instanceof NewBean))
                        {
                            if(DeploymentTypeManager.getInstance().isDeploymentTypeEnabled(bean.getDeploymentType()))
                            {
                                beans.add(bean);   
                            }                           
                        }                          
                    }                                   
                }
                else
                {
                    if(DeploymentTypeManager.getInstance().isDeploymentTypeEnabled(bean.getDeploymentType()))
                    {
                        beans.add(bean);  
                    }
                }
            }
        }

        return beans;
    }
   
    public static void checkUnproxiableApiType(Bean<?> bean, Class<? extends Annotation> scopeType)
    {
        Asserts.assertNotNull("bean", "bean parameter can not be null");
        Asserts.assertNotNull(scopeType, "scopeType parameter can not be null");

        Set<Type> types = bean.getTypes();
        Class<?> superClass = null;
        for (Type t : types)
        {
            Class<?> type = ClassUtil.getClazz(t);
           
            if (!type.isInterface())
            {
                if ((superClass == null) || (superClass.isAssignableFrom(type) && type != Object.class))
                {
                    superClass = type;
                }

            }
        }

        if (superClass != null && !superClass.equals(Object.class))
        {
            Constructor<?> cons = ClassUtil.isContaintNoArgConstructor(superClass);

            if (ClassUtil.isPrimitive(superClass) || ClassUtil.isArray(superClass) || ClassUtil.isFinal(superClass.getModifiers()) || ClassUtil.hasFinalMethod(superClass) || (cons == null || ClassUtil.isPrivate(cons.getModifiers())))
            {
                if (scopeType.isAnnotationPresent(NormalScope.class))
                {
                    throw new UnproxyableResolutionException("WebBeans with api type with normal scope must be proxiable to inject, but class : " + superClass.getName() + " is not proxiable type");
                }
            }

        }

    }

    public static void checkNullable(Class<?> type, AbstractBean<?> component)
    {
        Asserts.assertNotNull(type, "type parameter can not be null");
        Asserts.assertNotNull(component, "component parameter can not be null");

        if (type.isPrimitive())
        {
            if (component.isNullable())
            {
                throw new NullableDependencyException("Injection point for primitive type resolves webbeans component with return type : " + component.getReturnType().getName() + " with nullable");
            }
        }
    }

    /**
     * Configures the producer method specialization.
     *
     * @param component producer method component
     * @param method specialized producer method
     * @param superClass bean super class that has overriden method
     * @throws DefinitionException if the name is exist on the producer method when
     *         parent also has name
     * @throws WebBeansConfigurationException any other exceptions
     */
    public static void configureProducerSpecialization(AbstractBean<?> component, Method method, Class<?> superClass)
    {
        Method superMethod = ClassUtil.getClassMethodWithTypes(superClass, method.getName(), Arrays.asList(method.getParameterTypes()));
        if (superMethod == null)
        {
            throw new WebBeansConfigurationException("Producer method specialization is failed. Method " + method.getName() + " not found in super class : " + superClass.getName());
        }
       
        if (!AnnotationUtil.isAnnotationExist(superMethod.getAnnotations(), Produces.class))
        {
            throw new WebBeansConfigurationException("Producer method specialization is failed. Method " + method.getName() + " found in super class : " + superClass.getName() + " is not annotated with @Produces");
        }

        Annotation[] anns = AnnotationUtil.getQualifierAnnotations(superMethod.getAnnotations());

        for (Annotation ann : anns)
        {
            component.addQualifier(ann);
        }
       
        configuredProducerSpecializedName(component, method, superMethod);
       
        component.setSpecializedBean(true);
       
    }
   
    /**
     * Configures the name of the producer method for specializing the parent.
     *
     * @param component producer method component
     * @param method specialized producer method
     * @param superMethod overriden super producer method
     */
    public static void configuredProducerSpecializedName(AbstractBean<?> component,Method method,Method superMethod)
    {
        Asserts.assertNotNull(component,"component parameter can not be null");
        Asserts.assertNotNull(method,"method parameter can not be null");
        Asserts.assertNotNull(superMethod,"superMethod parameter can not be null");
       
        String name = null;
        boolean hasName = false;
        if(AnnotationUtil.isMethodHasAnnotation(superMethod, Named.class))
        {
          Named named =  superMethod.getAnnotation(Named.class);
          hasName = true;
          if(!named.value().equals(""))
          {
              name = named.value();
          }
          else
          {
              name = getProducerDefaultName(superMethod.getName());
          }
        }
        else
        {
            Annotation[] anns = AnnotationUtil.getStereotypeMetaAnnotations(superMethod.getAnnotations());
            for(Annotation ann : anns)
            {
                if(ann.annotationType().isAnnotationPresent(Stereotype.class))
                {
                    hasName = true;
                    name = getProducerDefaultName(superMethod.getName());
                    break;
                }
            }                       
        }
       
        if(hasName)
        {
            if(AnnotationUtil.isMethodHasAnnotation(method, Named.class))
            {
                throw new DefinitionException("Specialized method : " + method.getName() + " in class : " + component.getReturnType().getName() + " may not define @Named annotation");
            }
           
            component.setName(name);
        }
       
//        else
//        {
//            component.setName(name);
//        }
       
    }
   
    public static void checkInjectedMethodParameterConditions(Method method, Class<?> clazz)
    {
        Asserts.assertNotNull(method, "method parameter can not be null");
        Asserts.nullCheckForClass(clazz);

        if (AnnotationUtil.isMethodParameterAnnotationExist(method, Disposes.class) || AnnotationUtil.isMethodParameterAnnotationExist(method, Observes.class))
        {
            throw new WebBeansConfigurationException("Initializer method parameters in method : " + method.getName() + " in class : " + clazz.getName() + " can not be annotated with @Disposes or @Observers");

        }

    }

    public static void checkInterceptorResolverParams(Annotation... interceptorBindings)
    {
        if (interceptorBindings == null || interceptorBindings.length == 0)
        {
            throw new IllegalArgumentException("Manager.resolveInterceptors() method parameter interceptor bindings array argument can not be empty");
        }

        Annotation old = null;
        for (Annotation interceptorBinding : interceptorBindings)
        {
            if (old == null)
            {
                old = interceptorBinding;
            }
            else
            {
                if (old.equals(interceptorBinding))
                {
                    throw new IllegalArgumentException("Manager.resolveInterceptors() method parameter interceptor bindings array argument can not define duplicate binding annotation with name : @" + old.getClass().getName());
                }

                if (!AnnotationUtil.isInterceptorBindingAnnotation(interceptorBinding.annotationType()))
                {
                    throw new IllegalArgumentException("Manager.resolveInterceptors() method parameter interceptor bindings array can not contain other annotation that is not @InterceptorBinding");
                }

                old = interceptorBinding;
            }
        }
    }

    public static void checkDecoratorResolverParams(Set<Type> apiTypes, Annotation... qualifiers)
    {
        if (apiTypes == null || apiTypes.size() == 0)
        {
            throw new IllegalArgumentException("Manager.resolveDecorators() method parameter api types argument can not be empty");
        }

        Annotation old = null;
        for (Annotation qualifier : qualifiers)
        {
            if (old == null)
            {
                old = qualifier;
            }
            else
            {
                if (old.annotationType().equals(qualifier.annotationType()))
                {
                    throw new IllegalArgumentException("Manager.resolveDecorators() method parameter qualifiers array argument can not define duplicate qualifier annotation with name : @" + old.annotationType().getName());
                }

                if (!AnnotationUtil.isQualifierAnnotation(qualifier.annotationType()))
                {
                    throw new IllegalArgumentException("Manager.resolveDecorators() method parameter qualifiers array can not contain other annotation that is not @Qualifier");
                }

                old = qualifier;
            }
        }

    }
   
    /**
     * Returns true if instance injection point false otherwise.
     *
     * @param injectionPoint injection point definition
     * @return true if instance injection point
     */
    public static boolean checkObtainsInjectionPointConditions(InjectionPoint injectionPoint)
    {       
        Type type = injectionPoint.getType();
       
        Class<?> candidateClazz = null;
        if(type instanceof Class)
        {
            candidateClazz = (Class<?>)type;
        }
        else if(type instanceof ParameterizedType)
        {
            ParameterizedType pt = (ParameterizedType)type;
            candidateClazz = (Class<?>)pt.getRawType();
        }
       
        if(!candidateClazz.equals(Instance.class))
        {
            return false;
        }       
       
        Class<?> rawType = null;
       
        if(ClassUtil.isParametrizedType(injectionPoint.getType()))
        {
            ParameterizedType pt = (ParameterizedType)injectionPoint.getType();
           
            rawType = (Class<?>) pt.getRawType();
           
            Type[] typeArgs = pt.getActualTypeArguments();
           
            if(!(rawType.equals(Instance.class)))
            {
                throw new WebBeansConfigurationException("<Instance> field injection " + injectionPoint.toString() + " must have type javax.inject.Instance");
            }               
            else
            {                                       
                if(typeArgs.length == 1)
                {
                    Type actualArgument = typeArgs[0];
                   
                    if(ClassUtil.isParametrizedType(actualArgument) || ClassUtil.isWildCardType(actualArgument) || ClassUtil.isTypeVariable(actualArgument))
                    {                           
                        throw new WebBeansConfigurationException("<Instance> field injection " + injectionPoint.toString() + " actual type argument can not be Parametrized, Wildcard type or Type variable");                           
                    }
                                           
                    if(ClassUtil.isDefinitionConstainsTypeVariables((Class<?>)actualArgument))
                    {
                        throw new WebBeansConfigurationException("<Instance> field injection " + injectionPoint.toString() + " must not have TypeVariable or WildCard generic type argument");                           
                    }
                }
                else
                {
                    throw new WebBeansConfigurationException("<Instance> field injection " + injectionPoint.toString() + " must not have more than one actual type argument");
                }
            }                               
        }
        else
        {
            throw new WebBeansConfigurationException("<Instance> field injection " + injectionPoint.toString() + " must be defined as ParameterizedType with one actual type argument");
       
       
        return true;
    }

    public static <T> void checkPassivationScope(AbstractBean<T> component, NormalScope scope)
    {
        Asserts.assertNotNull(component, "component parameter can not be null");

        if(scope != null)
        {
            boolean passivating = scope.passivating();
            Class<T> clazz = component.getReturnType();

            if (passivating)
            {
                if (!component.isSerializable())
                {
                    throw new WebBeansPassivationException("WebBeans component implementation class : " + clazz.getName() + " with passivating scope @" + scope.annotationType().getName() + " must be Serializable");
                }
            }           
        }       
    }

   
    public static <T> void defineInterceptors(Class<T> clazz)
    {
        if (InterceptorsManager.getInstance().isInterceptorEnabled(clazz))
        {
            ManagedBean<T> component = null;

            InterceptorUtil.checkInterceptorConditions(clazz);
            component = ManagedBeanConfigurator.define(clazz, WebBeansType.INTERCEPTOR);

            if (component != null)
            {
                WebBeansInterceptorConfig.configureInterceptorClass((ManagedBean<Object>) component, clazz.getDeclaredAnnotations());
            }
        }

    }

   
    public static <T> void defineDecorators(Class<T> clazz)
    {
        if (DecoratorsManager.getInstance().isDecoratorEnabled(clazz))
        {
            ManagedBean<T> component = null;

            DecoratorUtil.checkDecoratorConditions(clazz);
            component = ManagedBeanConfigurator.define(clazz, WebBeansType.DECORATOR);

            if (component != null)
            {
                WebBeansDecoratorConfig.configureDecoratorClass((ManagedBean<Object>) component);
            }
        }
    }

    public static boolean isScopeTypeNormal(Class<? extends Annotation> scopeType)
    {
        Asserts.assertNotNull(scopeType, "scopeType argument can not be null");

        if (scopeType.isAnnotationPresent(NormalScope.class))
        {
            return true;
        }
        else if(scopeType.isAnnotationPresent(Scope.class))
        {
            return false;
        }
        else
        {
            throw new IllegalArgumentException("scopeType argument must be annotated with @Scope or @NormalScope");
        }
    }
   
    public static void checkNullInstance(Object instance,Class<?> scopeType, String errorMessage)
    {
        if (instance == null)
        {
            if (!scopeType.equals(Dependent.class))
            {
                throw new IllegalProductException(errorMessage);
            }
        }
       
    }
   
    public static void checkSerializableScopeType(Class<?> scopeType, boolean isSerializable, String errorMessage)
    {
        // Scope type check
        NormalScope scope = scopeType.getAnnotation(NormalScope.class);
        if(scope != null)
        {
            if (scope.passivating())
            {
                if (!isSerializable)
                {
                    throw new IllegalProductException(errorMessage);
                }
            }           
        }
    }
   
    public static boolean isManagedBean(AbstractBean<?> component)
    {
        if(component.getWebBeansType().equals(WebBeansType.MANAGED) ||
                component.getWebBeansType().equals(WebBeansType.INTERCEPTOR) ||
                component.getWebBeansType().equals(WebBeansType.DECORATOR))
        {
            return true;
        }
       
        return false;
    }
   
    /**
     * Returns true if bean is an enterprise bean, false otherwise.
     * @param bean bean instance
     * @return true if bean is an enterprise bean
     */
    public static boolean isEnterpriseBean(AbstractBean<?> bean)
    {
        Asserts.assertNotNull(bean,"Bean is null");
       
        if(bean.getWebBeansType().equals(WebBeansType.ENTERPRISE))
        {
            return true;
        }
       
        return false;
    }
   
    public static void addInjectedImplicitEventComponent(InjectionPoint injectionPoint)
    {
        Type type = injectionPoint.getType();
       
        if(!(type instanceof ParameterizedType))
        {
            return;
        }
       
        Type[] args = new Type[0];
       
        Class<?> clazz = null;
        if (type instanceof ParameterizedType)
        {
            ParameterizedType pt = (ParameterizedType) type;
            args = pt.getActualTypeArguments();
        }
       
        clazz = (Class<?>)args[0];
       
        Annotation[] qualifiers = new Annotation[injectionPoint.getQualifiers().size()];
        qualifiers = injectionPoint.getQualifiers().toArray(qualifiers);
       
        Bean<?> bean = createObservableImplicitComponent(EventImpl.class, clazz, qualifiers);
        BeanManagerImpl.getManager().addBean(bean);                 
    }
   
   
    public static <T> void addInjectedImplicitInstanceComponent(InjectionPoint injectionPoint)
    {
        ParameterizedType genericType = (ParameterizedType)injectionPoint.getType();
       
        Class<Instance<T>> clazz = (Class<Instance<T>>)genericType.getRawType();
       
        Annotation[] qualifiers = new Annotation[injectionPoint.getQualifiers().size()];
        qualifiers = injectionPoint.getQualifiers().toArray(qualifiers);
       
        Bean<Instance<T>> bean = createInstanceComponent(genericType,clazz, genericType.getActualTypeArguments()[0], qualifiers);
        BeanManagerImpl.getManager().addBean(bean);
       
    }
   
    public static Bean<?> getMostSpecializedBean(BeanManager manager, Bean<?> component)
    {
        Set<Bean<?>> beans = manager.getBeans(component.getBeanClass(), AnnotationUtil.getAnnotationsFromSet(component.getQualifiers()));
               
        for(Bean<?> bean : beans)
        {
            Bean<?> find = bean;
           
            if(!find.equals(component))
            {
                if(AnnotationUtil.isAnnotationExistOnClass(find.getBeanClass(), Specializes.class))
                {
                    return getMostSpecializedBean(manager, find);
                }               
            }           
        }
       
        return component;
    }     
   
    public static boolean isDeploymentTypeEnabled(Class<? extends Annotation> deploymentType)
    {
        Asserts.assertNotNull(deploymentType, "deplymentType parameter can not be null");
       
        if (!DeploymentTypeManager.getInstance().isDeploymentTypeEnabled(deploymentType))
        {
            return false;
        }
       
        return true;       
    }
   
    /**
     * Returns <code>ProcessAnnotatedType</code> event.
     * @param <T> bean type
     * @param clazz bean class
     * @return event
     */
    public static <T> GProcessAnnotatedType fireProcessAnnotatedTypeEvent(AnnotatedType<T> annotatedType)
    {               
        GProcessAnnotatedType processAnnotatedEvent = new GProcessAnnotatedType(annotatedType);
       
        //Fires ProcessAnnotatedType
        BeanManagerImpl.getManager().fireEvent(processAnnotatedEvent, new Annotation[0]);
       
        return processAnnotatedEvent;       
    }
   
    /**
     * Returns <code>ProcessInjectionTarget</code> event.
     * @param <T> bean type
     * @param bean bean instance
     * @return event
     */
    public static <T> GProcessInjectionTarget fireProcessInjectionTargetEvent(AbstractInjectionTargetBean<T> bean)
    {
        AnnotatedType<T> annotatedType = AnnotatedElementFactory.newAnnotatedType(bean.getReturnType());
        InjectionTargetProducer<T> injectionTarget = new InjectionTargetProducer<T>(bean);
        GProcessInjectionTarget processInjectionTargetEvent = new GProcessInjectionTarget(injectionTarget,annotatedType);
       
        //Fires ProcessInjectionTarget
        BeanManagerImpl.getManager().fireEvent(processInjectionTargetEvent, new Annotation[0]);
       
        return processInjectionTargetEvent;
       
    }
   
    public static GProcessProducer fireProcessProducerEventForMethod(ProducerMethodBean<?> producerMethod,AnnotatedMethod<?> method)
    {        
        GProcessProducer producerEvent = new GProcessProducer(method);
       
        //Fires ProcessProducer for methods
        BeanManagerImpl.getManager().fireEvent(producerEvent, new Annotation[0]);
       
        return producerEvent;
    }
   
    public static GProcessProducer fireProcessProducerEventForField(ProducerFieldBean<?> producerField,AnnotatedField<?> field)
    {        
        GProcessProducer producerEvent = new GProcessProducer(field);
       
        //Fires ProcessProducer for fields
        BeanManagerImpl.getManager().fireEvent(producerEvent, new Annotation[0]);
       
        return producerEvent;
    }
   
    public static void fireProcessProducerMethodBeanEvent(Map<ProducerMethodBean<?>,AnnotatedMethod<?>> annotatedMethods)
    {
        for(ProducerMethodBean<?> bean : annotatedMethods.keySet())
        {
            AnnotatedMethod<?> annotatedMethod = annotatedMethods.get(bean);               
            Method disposal = bean.getDisposalMethod();
           
            AnnotatedMethod<?> disposalAnnotated = null;
            GProcessProducerMethod processProducerMethodEvent = null;
            if(disposal != null)
            {
                disposalAnnotated = AnnotatedElementFactory.newAnnotatedMethod(disposal, bean.getParent().getReturnType());
                processProducerMethodEvent = new GProcessProducerMethod(bean,annotatedMethod,disposalAnnotated.getParameters().get(0));               
            }
            else
            {
                processProducerMethodEvent = new GProcessProducerMethod(bean,annotatedMethod,null);
            }
           

            //Fires ProcessProducer
            BeanManagerImpl.getManager().fireEvent(processProducerMethodEvent, new Annotation[0]);
        }               
    }
   
    public static void fireProcessProducerFieldBeanEvent(Map<ProducerFieldBean<?>,AnnotatedField<?>> annotatedFields)
    {
        for(ProducerFieldBean<?> bean : annotatedFields.keySet())
        {
            AnnotatedField<?> field = annotatedFields.get(bean);
           
            GProcessProducerField processProducerFieldEvent = new GProcessProducerField(bean,field);
           
            //Fire ProcessProducer
            BeanManagerImpl.getManager().fireEvent(processProducerFieldEvent, new Annotation[0]);
        }       
    }
   
    /**
     * Returns true if bean instance is an enterprise bean instance
     * false otherwise.
     * @param beanInstance bean instance
     * @return true if bean instance is an enterprise bean instance
     */
    public static boolean isBeanHasEnterpriseMarker(Object beanInstance)
    {
        Asserts.assertNotNull(beanInstance,"Bean instance is null");
       
        if(beanInstance instanceof EnterpriseBeanMarker)
        {
            return true;
        }
       
        return false;
    }
}
TOP

Related Classes of org.apache.webbeans.util.WebBeansUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.