Package org.apache.webbeans.xml

Source Code of org.apache.webbeans.xml.WebBeansXMLConfigurator

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

import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.decorator.Decorator;
import javax.enterprise.context.NormalScope;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.deployment.DeploymentType;
import javax.enterprise.inject.deployment.Production;
import javax.inject.Inject;
import javax.inject.Scope;
import javax.interceptor.Interceptor;

import org.apache.webbeans.WebBeansConstants;
import org.apache.webbeans.annotation.CurrentLiteral;
import org.apache.webbeans.annotation.ProductionLiteral;
import org.apache.webbeans.component.AbstractBean;
import org.apache.webbeans.component.xml.XMLManagedBean;
import org.apache.webbeans.component.xml.XMLProducerBean;
import org.apache.webbeans.config.DefinitionUtil;
import org.apache.webbeans.config.ManagedBeanConfigurator;
import org.apache.webbeans.config.OpenWebBeansConfiguration;
import org.apache.webbeans.container.BeanManagerImpl;
import org.apache.webbeans.decorator.DecoratorsManager;
import org.apache.webbeans.deployment.DeploymentTypeManager;
import org.apache.webbeans.exception.WebBeansConfigurationException;
import org.apache.webbeans.exception.definition.NonexistentConstructorException;
import org.apache.webbeans.exception.definition.NonexistentFieldException;
import org.apache.webbeans.exception.definition.NonexistentMethodException;
import org.apache.webbeans.exception.definition.NonexistentTypeException;
import org.apache.webbeans.exception.inject.DefinitionException;
import org.apache.webbeans.exception.inject.DeploymentException;
import org.apache.webbeans.inject.AlternativesManager;
import org.apache.webbeans.inject.impl.InjectionPointFactory;
import org.apache.webbeans.inject.xml.XMLInjectableConstructor;
import org.apache.webbeans.inject.xml.XMLInjectionModelType;
import org.apache.webbeans.inject.xml.XMLInjectionPointModel;
import org.apache.webbeans.intercept.InterceptorsManager;
import org.apache.webbeans.jms.JMSManager;
import org.apache.webbeans.jms.JMSModel;
import org.apache.webbeans.jms.JMSModel.JMSType;
import org.apache.webbeans.logger.WebBeansLogger;
import org.apache.webbeans.plugins.OpenWebBeansEjbPlugin;
import org.apache.webbeans.plugins.OpenWebBeansJmsPlugin;
import org.apache.webbeans.plugins.PluginLoader;
import org.apache.webbeans.proxy.JavassistProxyFactory;
import org.apache.webbeans.util.AnnotationUtil;
import org.apache.webbeans.util.Asserts;
import org.apache.webbeans.util.ClassUtil;
import org.apache.webbeans.util.WebBeansUtil;
import org.dom4j.Element;

/**
* Configures the web beans from the xml declerations.
*/
@SuppressWarnings("unchecked")
public final class WebBeansXMLConfigurator
{
    private static final WebBeansLogger logger = WebBeansLogger.getLogger(WebBeansXMLConfigurator.class);
   
    /** Enabled Deploy element check */
    private boolean DEPLOY_IS_DEFINED = false;

    /** Enabled Interceptors element check */
    private boolean INTERCEPTORS_IS_DEFINED = false;

    /** Enabled Decorators element check */
    private boolean DECORATORS_IS_DEFINED = false;   

    /** Current configuration file name */
    private String CURRENT_SCAN_FILE_NAME = null;
   
    /**OWB specific or not*/
    private boolean owbSpecificConfiguration = false;

    /** Annotation type manager that manages the XML defined annotations */
    private XMLAnnotationTypeManager xmlAnnotTypeManager = XMLAnnotationTypeManager.getInstance();

    /**
     * Creates a new instance of the <code>WebBeansXMLConfigurator</code>
     */
    public WebBeansXMLConfigurator()
    {
        String usage = OpenWebBeansConfiguration.getInstance().getProperty(OpenWebBeansConfiguration.USE_OWB_SPECIFIC_XML_CONFIGURATION);
        this.owbSpecificConfiguration = Boolean.parseBoolean(usage);
    }
   
    /**
     * Configures XML configuration file.
     * @param xmlStream xml configuration file
     */
    public void configure(InputStream xmlStream)
    {
        try
        {
            if(xmlStream.available() > 0)
            {
                //Use OWB Specific XML Configuration
                if(this.owbSpecificConfiguration)
                {
                    configureOwbSpecific(xmlStream, "No-name XML Stream");   
                }
                else
                {
                    configureSpecSpecific(xmlStream, "No-name XML Stream");
                }
                   
            }
        }
        catch (IOException e)
        {
            throw new WebBeansConfigurationException(e);
        }
       
    }
   
    /**
     * Configures XML configuration file.
     * @param xmlStream xml configuration file
     * @param fileName file name
     */
    public void configure(InputStream xmlStream, String fileName)
    {
        try
        {
            if(xmlStream.available() > 0)
            {
                //Use OWB Specific XML Configuration
                if(this.owbSpecificConfiguration)
                {
                    configureOwbSpecific(xmlStream, fileName);   
                }
                else
                {
                    configureSpecSpecific(xmlStream, fileName);
                }
                   
            }
        }
        catch (IOException e)
        {
            throw new WebBeansConfigurationException(e);
        }
       
    }
   

    /**
     * Configures the web beans from the given input stream.
     *
     * @param xmlStream xml file containing the web beans definitions.
     * @param fileName name of the configuration file
     */
    public void configureOwbSpecific(InputStream xmlStream, String fileName)
    {
        try
        {
            if(xmlStream.available() > 0)
            {
                Asserts.assertNotNull(xmlStream,"xmlStream parameter can not be null!");
                Asserts.assertNotNull(fileName,"fileName parameter can not be null!");
               
                CURRENT_SCAN_FILE_NAME = fileName;
               
                //Get root element of the XML document
                Element webBeansRoot = XMLUtil.getRootElement(xmlStream);
               
                //Start configuration
                configureOwbSpecific(webBeansRoot);           
            }
        }
        catch (IOException e)
        {
            throw new WebBeansConfigurationException(e);
        }
    }
   
    /**
     * Configures the web beans from the given input stream.
     *
     * @param xmlStream xml file containing the web beans definitions.
     * @param fileName name of the configuration file
     */
    public void configureSpecSpecific(InputStream xmlStream, String fileName)
    {
        try
        {
            if(xmlStream.available() > 0)
            {
                Asserts.assertNotNull(xmlStream,"xmlStream parameter can not be null!");
                Asserts.assertNotNull(fileName,"fileName parameter can not be null!");
               
                CURRENT_SCAN_FILE_NAME = fileName;
               
                //Get root element of the XML document
                Element webBeansRoot = XMLUtil.getSpecStrictRootElement(xmlStream);
               
                //Start configuration
                configureSpecSpecific(webBeansRoot);           
            }
        }
        catch (IOException e)
        {
            throw new WebBeansConfigurationException(e);
        }
    }
   

    /**
     * Configures the xml file root element.
     *
     * @param webBeansRoot root element of the configuration xml file
     */
    private void configureOwbSpecific(Element webBeansRoot)
    {
        List<Element> webBeanDeclerationList = new ArrayList<Element>();
        List<Element> childs = webBeansRoot.elements();
        Iterator<Element> it = childs.iterator();

        Element child = null;
        while (it.hasNext())
        {
            child = it.next();

            /* WebBean element decleration */
            if (XMLUtil.isElementWebBeanDeclaration(child))
            {
                webBeanDeclerationList.add(child);

            }
            /* <Deploy> element decleration */
            else if (XMLUtil.isElementDeployDeclaration(child))
            {
                if (DEPLOY_IS_DEFINED)
                {
                    throw new DeploymentException("There can not be more than one web-beans.xml file that declares <Deploy> element");
                }
                else
                {
                    if (!XMLUtil.isElementChildExist(child, WebBeansConstants.WEB_BEANS_XML_STANDART_ELEMENT))
                    {
                        throw new DeploymentException("<Deploy> element must have <Standard/> deployment type in the web-beans.xml");
                    }
                   
                    DeploymentTypeManager.getInstance().removeProduction();
                   
                    configureDeploymentTypes(child);
                    DEPLOY_IS_DEFINED = true;

                }
            }
            /* <Interceptors> element decleration */
            else if (XMLUtil.isElementInterceptorsDeclaration(child))
            {
                if (INTERCEPTORS_IS_DEFINED)
                {
                    throw new WebBeansConfigurationException("There can not be more than one web-beans.xml file that declares <Interceptors> element");
                }
                else
                {
                    configureInterceptorsElement(child);
                    INTERCEPTORS_IS_DEFINED = true;

                }
            }
            /* <Decorators> element decleration */
            else if (XMLUtil.isElementDecoratosDeclaration(child))
            {
                if (DECORATORS_IS_DEFINED)
                {
                    throw new WebBeansConfigurationException("There can not be more than one web-beans.xml file that declares <Decorators> element");
                }
                else
                {
                    configureDecoratorsElement(child);
                    DECORATORS_IS_DEFINED = true;

                }
            }
            /* <BindingType> annotation element decleration */
            else if (XMLUtil.isElementBindingTypeDecleration(child))
            {
                addNewBindingType(child);

            }
           
            //X TODO <Resource> annotation element declaration */
           
            /* <InterceptorBindingType> annotation element decleration */
            else if (XMLUtil.isElementInterceptorBindingTypeDecleration(child))
            {
                addNewInterceptorBindingType(child);

            }
           
            /* <Stereotype> annotation element decleration */
            else if (XMLUtil.isElementStereoTypeDecleration(child))
            {
                addNewStereoTypeType(child);
            }
            else if(XMLUtil.getName(child).equals(WebBeansConstants.WEB_BEANS_XML_OWB_SPECIFIC_ALTERNATIVES))
            {
                configureAlternativesElement(child);
            }
           
        }

        /*
         * If no <Deploy> element is defined in any webbeans.xml in the current
         * application
         */
        if (!DEPLOY_IS_DEFINED)
        {
            DeploymentTypeManager.getInstance().addNewDeploymentType(Production.class, 1);
        }

        // Configures the WebBeans components
        configureWebBeansComponents(webBeanDeclerationList);

    }

    /**
     * Configures the xml file root element.
     *
     * @param webBeansRoot root element of the configuration xml file
     */
    private void configureSpecSpecific(Element webBeansRoot)
    {
        List<Element> childs = webBeansRoot.elements();
        Iterator<Element> it = childs.iterator();

        Element child = null;
        while (it.hasNext())
        {
            child = it.next();

            /* <Deploy> element decleration */
            if (XMLUtil.getName(child).equals(WebBeansConstants.WEB_BEANS_XML_SPEC_SPECIFIC_DEPLOY_ELEMENT))
            {
                if (DEPLOY_IS_DEFINED)
                {
                    throw new DeploymentException("There can not be more than one web-beans.xml file that declares <deploy> element");
                }
                else
                {
                    if (!XMLUtil.isElementChildExist(child, WebBeansConstants.WEB_BEANS_XML_STANDART_ELEMENT))
                    {
                        throw new DeploymentException("<Deploy> element must have <Standard/> deployment type in the web-beans.xml");
                    }
                   
                    DeploymentTypeManager.getInstance().removeProduction();
                   
                    configureDeploymentTypes(child);
                    DEPLOY_IS_DEFINED = true;

                }
            }
            /* <Interceptors> element decleration */
            else if (XMLUtil.getName(child).equals(WebBeansConstants.WEB_BEANS_XML_SPEC_SPECIFIC_INTERCEPTORS_ELEMENT))
            {
                if (INTERCEPTORS_IS_DEFINED)
                {
                    throw new WebBeansConfigurationException("There can not be more than one web-beans.xml file that declares <interceptors> element");
                }
                else
                {
                    configureInterceptorsElement(child);
                    INTERCEPTORS_IS_DEFINED = true;

                }
            }
            /* <Decorators> element decleration */
            else if (XMLUtil.getName(child).equals(WebBeansConstants.WEB_BEANS_XML_SPEC_SPECIFIC_DECORATORS_ELEMENT))
            {
                if (DECORATORS_IS_DEFINED)
                {
                    throw new WebBeansConfigurationException("There can not be more than one web-beans.xml file that declares <decorators> element");
                }
                else
                {
                    configureDecoratorsElement(child);
                    DECORATORS_IS_DEFINED = true;

                }
            }
            else if(XMLUtil.getName(child).equals(WebBeansConstants.WEB_BEANS_XML_SPEC_SPECIFIC_ALTERNATIVES))
            {
                configureAlternativesElement(child);
            }
        }

        /*
         * If no <Deploy> element is defined in any webbeans.xml in the current
         * application
         */
        if (!DEPLOY_IS_DEFINED)
        {
            DeploymentTypeManager.getInstance().addNewDeploymentType(Production.class, 1);
        }

    }
   
    /**
     * Configures the webbeans defined in the xml file.
     *
     * @param listOfWebBeanDecleration list of element that specifies new
     *            webbean decleration
     */
    private void configureWebBeansComponents(List<Element> listOfWebBeanDecleration)
    {
        if (!listOfWebBeanDecleration.isEmpty())
        {
            Iterator<Element> it = listOfWebBeanDecleration.iterator();
            while (it.hasNext())
            {
                Element child = it.next();
                /* JMS webbeans */
                if (XMLUtil.isElementJMSDeclaration(child))
                {
                    configureJMSEndpointComponent(child);
                }
                /* Simple or Enterprise webbean */
                else
                {
                    configureNewWebBeanComponent(child);
                }
            }
        }
    }

    /**
     * Configure and add new binding type annotation.
     *
     * @param bindingTypeElement new binding type element
     */
    private void addNewBindingType(Element bindingTypeElement)
    {
        Class<?> clazz = XMLUtil.getElementJavaType(bindingTypeElement);
        if (clazz == null)
        {
            throw new NonexistentTypeException(createConfigurationFailedMessage() + "Binding type with given class : " + bindingTypeElement.getName() + " not found");
        }

        Class<? extends Annotation> clazzAnnot = null;
        if (!clazz.isAnnotation())
        {
            throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Binding type with given class : " + bindingTypeElement.getName() + " is not an annotation type");
        }
        else
        {
            clazzAnnot = (Class<? extends Annotation>) clazz;
        }

        if (xmlAnnotTypeManager.isBindingTypeExist(clazzAnnot))
        {
            throw new DeploymentException(createConfigurationFailedMessage() + "Binding type with given class : " + bindingTypeElement.getName() + " is already defined in the XML");
        }

        xmlAnnotTypeManager.addBindingType(clazzAnnot);
    }

    /**
     * Configures and adds new interceptor binding type annotation.
     *
     * @param interceptorBindingTypeElement new interceptor binding type element
     */
    private void addNewInterceptorBindingType(Element interceptorBindingTypeElement)
    {
        Class<?> clazz = XMLUtil.getElementJavaType(interceptorBindingTypeElement);
        if (clazz == null)
        {
            throw new NonexistentTypeException(createConfigurationFailedMessage() + "InterceptorBinding type with given class : " + interceptorBindingTypeElement.getName() + " not found");
        }

        Class<? extends Annotation> clazzAnnot = null;
        if (!clazz.isAnnotation())
        {
            throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "InterceptorBinding type with given class : " + interceptorBindingTypeElement.getName() + " is not an annotation type");
        }
        else
        {
            clazzAnnot = (Class<? extends Annotation>) clazz;
        }

        if (xmlAnnotTypeManager.isInterceptorBindingTypeExist(clazzAnnot))
        {
            throw new DeploymentException(createConfigurationFailedMessage() + "InterceptorBinding type with given class : " + interceptorBindingTypeElement.getName() + " is already defined in the XML");
        }

        List<Element> childs = interceptorBindingTypeElement.elements();
        for (Element child : childs)
        {
            Class<?> clz = XMLUtil.getElementJavaType(child);
            if (clz == null)
            {
                throw new NonexistentTypeException(createConfigurationFailedMessage() + "InterceptorBinding type with given class : " + XMLUtil.getElementJavaClassName(child) + " not found " + "in namespace : " + XMLUtil.getElementNameSpace(child));
            }

            if (!clz.isAnnotation() || !AnnotationUtil.isInterceptorBindingAnnotation((Class<? extends Annotation>) clz))
            {
                throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "InterceptorBinding type with given class : " + XMLUtil.getElementJavaClassName(child) + " is not interceptor binding annotation type");
            }

            Annotation inherited = XMLUtil.getXMLDefinedAnnotationMember(child, (Class<? extends Annotation>) clz, createConfigurationFailedMessage());
            xmlAnnotTypeManager.addInterceotorBindingTypeInheritAnnotation(clazzAnnot, inherited);
        }

    }

    /**
     * Configures and adds new stereotype annotation.
     *
     * @param stereoTypeElement new stereotype annotation element
     */
    private void addNewStereoTypeType(Element stereoTypeElement)
    {
        Class<?> clazz = XMLUtil.getElementJavaType(stereoTypeElement);
        if (clazz == null)
        {
            throw new NonexistentTypeException(createConfigurationFailedMessage() + "Stereotype with given class : " + stereoTypeElement.getName() + " not found");
        }

        Class<? extends Annotation> clazzAnnot = null;
        if (!clazz.isAnnotation())
        {
            throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Stereotype with given class : " + stereoTypeElement.getName() + " is not an annotation type");
        }
        else
        {
            clazzAnnot = (Class<? extends Annotation>) clazz;
        }

        if (xmlAnnotTypeManager.isStereoTypeExist(clazzAnnot))
        {
            throw new DeploymentException(createConfigurationFailedMessage() + "Stereotype with given class : " + stereoTypeElement.getName() + " is already defined in the XML");
        }

        xmlAnnotTypeManager.addStereoType(clazzAnnot, stereoTypeElement, clazzAnnot.getName(), createConfigurationFailedMessage());

    }

    /**
     * Configures enablements of the interceptors.
     *
     * @param interceptorsElement interceptors element
     */
    private void configureInterceptorsElement(Element interceptorsElement)
    {
        List<Element> childs = interceptorsElement.elements();
        Iterator<Element> itChilds = childs.iterator();

        InterceptorsManager manager = InterceptorsManager.getInstance();
        while (itChilds.hasNext())
        {
            Element child = itChilds.next();
            Class<?> clazz = null;
           
            if(this.owbSpecificConfiguration)
            {
                clazz = XMLUtil.getElementJavaType(child);
            }
            else
            {
                clazz = ClassUtil.getClassFromName(child.getTextTrim());
            }

            if (clazz == null)
            {
                throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Interceptor class : " + XMLUtil.getName(child) + " not found");
            }
            else
            {
                if (!AnnotationUtil.isInterceptorBindingMetaAnnotationExist(clazz.getDeclaredAnnotations()))
                {
                    throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Interceptor class : " + XMLUtil.getName(child) + " must have at least one @InterceptorBindingType");
                }

                if (manager.isInterceptorEnabled(clazz))
                {
                    throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Interceptor class : " + XMLUtil.getName(child) + " is already defined");
                }

                manager.addNewInterceptor(clazz);
            }

        }

    }

    /**
     * Configures enablements of the decorators.
     *
     * @param decoratorsElement decorators element
     */
    private void configureDecoratorsElement(Element decoratorsElement)
    {
        List<Element> childs = decoratorsElement.elements();
        Iterator<Element> itChilds = childs.iterator();

        DecoratorsManager manager = DecoratorsManager.getInstance();
        while (itChilds.hasNext())
        {
            Element child = itChilds.next();
            Class<?> clazz = null;
           
            if(this.owbSpecificConfiguration)
            {
                clazz = XMLUtil.getElementJavaType(child);
            }
            else
            {
                clazz = ClassUtil.getClassFromName(child.getTextTrim());
            }

            if (clazz == null)
            {
                throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Decorator class : " + XMLUtil.getName(child) + " not found");
            }
            else
            {

                if (manager.isDecoratorEnabled(clazz))
                {
                    throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Decorator class : " + XMLUtil.getName(child) + " is already defined");
                }

                manager.addNewDecorator(clazz);
            }

        }

    }
   
    /**
     * Configures enablements of the decorators.
     *
     * @param decoratorsElement decorators element
     */
    private void configureAlternativesElement(Element alternativesElement)
    {
        List<Element> childs = alternativesElement.elements();
        Iterator<Element> itChilds = childs.iterator();

        while (itChilds.hasNext())
        {
            Element child = itChilds.next();

            if(XMLUtil.getName(child).equals(WebBeansConstants.WEB_BEANS_XML_SPEC_SPECIFIC_STEREOTYPE) ||
                    XMLUtil.getName(child).equals(WebBeansConstants.WEB_BEANS_XML_OWB_SPECIFIC_STEREOTYPE))
            {
                addAlternative(child, true);
            }
            else if(XMLUtil.getName(child).equals(WebBeansConstants.WEB_BEANS_XML_SPEC_SPECIFIC_CLASS)
                    || XMLUtil.getName(child).equals(WebBeansConstants.WEB_BEANS_XML_OWB_SPECIFIC_CLASS))
            {
                addAlternative(child, false);
            }
            else
            {
                logger.warn("Alternative XML content is wrong. Child of <alternatives> must be <class>,<stereotype> but found " + XMLUtil.getName(child));
            }           
        }
    }
   
    private void addAlternative(Element child, boolean isStereoType)
    {
        Class<?> clazz = null;
       
        if(this.owbSpecificConfiguration)
        {
            clazz = XMLUtil.getElementJavaType(child);
        }
        else
        {
            clazz = ClassUtil.getClassFromName(child.getTextTrim());
        }

        if (clazz == null)
        {
            throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Alternative class : " + XMLUtil.getName(child) + " not found");
        }
        else
        {
            AlternativesManager manager = AlternativesManager.getInstance();
            if(isStereoType)
            {
                manager.addStereoTypeAlternative(clazz);
            }
            else
            {
                manager.addClazzAlternative(clazz);
            }
        }       
    }
   

    /**
     * Configures enablements of the deployment types.
     *
     * @param deployElement deploy element
     */
    private void configureDeploymentTypes(Element deployElement)
    {
        List<Element> childs = deployElement.elements();
        Iterator<Element> itChilds = childs.iterator();

        int j = 1;
        while (itChilds.hasNext())
        {
            Element child = itChilds.next();
            Class<?> clazz = null;
           
            if(this.owbSpecificConfiguration)
            {
                clazz = XMLUtil.getElementJavaType(child);
            }
            else
            {
                clazz = ClassUtil.getClassFromName(child.getTextTrim());
            }

            if (clazz == null)
            {
                throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "@DeploymentType annotation with name : " + XMLUtil.getName(child) + " not found");
            }
            else
            {
                if (!clazz.isAnnotation())
                    throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "@DeploymentType annotation with name : " + XMLUtil.getName(child) + " is not annotation type");
                else
                {
                    Annotation ann = clazz.getAnnotation(DeploymentType.class);
                    if (ann == null)
                    {
                        throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "@DeploymentType annotation with name : " + XMLUtil.getName(child) + " is not deployment type annotation");
                    }
                    else
                    {
                        DeploymentTypeManager.getInstance().addNewDeploymentType((Class<? extends Annotation>) clazz, j++);
                    }
                }
            }
        }
    }

    /**
     * Configures new webbeans component from the given webbeans element.
     *
     * @param webBeanElement web beans element
     */
    private void configureNewWebBeanComponent(Element webBeanElement)
    {
        Class<?> clazz = XMLUtil.getElementJavaType(webBeanElement);

        if (clazz == null)
        {
            throw new NonexistentTypeException(createConfigurationFailedMessage() + "Class with name : " + XMLUtil.getName(webBeanElement) + " is not found in namespace " + XMLUtil.getElementNameSpace(webBeanElement));
        }

        boolean ok = false;

        /* Enterprise WebBean */
        OpenWebBeansEjbPlugin plugin = PluginLoader.getInstance().getEjbPlugin();
        if (plugin != null && plugin.isSessionBean(clazz))
        {
            // Configure for EJB
            configureEJBWebBean(clazz);
            ok = true;
        }
        else
        {
            /* Simple WebBeans */
            if (ManagedBeanConfigurator.isManagedBean(clazz))
            {
                // Configure Simple WebBean
                configureSimpleWebBean(clazz, webBeanElement);
                ok = true;
            }
        }

        /* If not applicable for configuration */
        if (!ok)
        {
            throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Given class with name : " + clazz.getName() + " is not resolved to any WebBeans type in {Simple WebBeans, Enterprise WebBeans, JMS WebBeans}");
        }

    }

    /**
     * Configures the simple webbean from the class.
     *
     * @param simpleClass concrete java class defined in XML
     * @param webBeanDecleration webbeans decleration root element
     */
    public <T> XMLManagedBean<T> configureSimpleWebBean(Class<T> simpleClass, Element webBeanDecleration)
    {
        /* Checking XML defined simple webbeans condition check. Spec : 3.2.4 */
        XMLDefinitionUtil.checkSimpleWebBeansInXML(simpleClass, webBeanDecleration, createConfigurationFailedMessage());

        /* If interceptor, check this is enabled */
        if (XMLUtil.isElementChildExistWithWebBeansNameSpace(webBeanDecleration, WebBeansConstants.WEB_BEANS_XML_INTERCEPTOR_ELEMENT))
        {
            if (!InterceptorsManager.getInstance().isInterceptorEnabled(simpleClass))
            {
                return null;
            }
        }

        /* If decorator, check this is enabled */
        if (XMLUtil.isElementChildExistWithWebBeansNameSpace(webBeanDecleration, WebBeansConstants.WEB_BEANS_XML_DECORATOR_ELEMENT))
        {
            if (!DecoratorsManager.getInstance().isDecoratorEnabled(simpleClass))
            {
                return null;
            }
        }

        /* Create new XML component with class name */
        XMLManagedBean<T> component = new XMLManagedBean<T>(simpleClass);

        /* Configures API type of the webbeans component */
        DefinitionUtil.defineApiTypes(component, simpleClass);

        /* Configures child elements of this webbeans decleration element */
        configureWebBeanDeclerationChilds(component, webBeanDecleration);

        /* Check if the deployment type is enabled. */
        if (!DeploymentTypeManager.getInstance().isDeploymentTypeEnabled(component.getDeploymentType())) // Maybe
        {
            component = null;

        }
        /* Add to the manager */
        else
        {
            BeanManagerImpl.getManager().addBean(component);
        }

        return component;
    }

    /**
     * Configures the childs element of the given webbeans decleration element.
     *
     * @param component xml webbeans element
     * @param webBeanDecleration webbeans element
     */
    private <T> void configureWebBeanDeclerationChilds(XMLManagedBean<T> component, Element webBeanDecleration)
    {
        List<Element> childs = webBeanDecleration.elements();
        Iterator<Element> it = childs.iterator();

        Element child = null;

        /* Constructor api type list */
        List<Class<?>> constTypeList = new ArrayList<Class<?>>();

        /* Constructor parameters element */
        List<Element> constructorParameterElementList = new ArrayList<Element>();

        /* Annotation set defined for webbeans */
        List<Class<? extends Annotation>> annotationSet = new ArrayList<Class<? extends Annotation>>();

        /* Annotation defined element list */
        List<Element> annotationElementList = new ArrayList<Element>();

        boolean isConstructor = false;
        String fieldOrMethodName = null;
        while (it.hasNext())
        {
            child = it.next();
            Class<?> type = XMLUtil.getElementJavaType(child);

            boolean isElementApplicable = false;

            // Java type then 2 possible outcome, Annotation type meta-data or
            // constructor
            if (type != null)
            {
                if (type.isAnnotation())
                {
                    // Annotation types defined on the webbeans
                    Class<? extends Annotation> annot = (Class<Annotation>) type;
                    annotationSet.add(annot);
                    annotationElementList.add(child);

                    isElementApplicable = true;

                }
                else
                {
                    if (!isConstructor)
                    {
                        isConstructor = true;
                    }

                    /* Constructor parameter Element */
                    constructorParameterElementList.add(child);

                    // Adding constructor parameter class types
                    constTypeList.add(type);

                    isElementApplicable = true;

                }
            }
            // Field or method decleration
            else
            {
                // Namespace check
                if (XMLUtil.getElementNameSpace(child).equals(XMLUtil.getElementNameSpace(webBeanDecleration)))
                {
                    String name = XMLUtil.getName(child);

                    // Duplicate definition for field/method
                    if (fieldOrMethodName != null)
                    {
                        if (fieldOrMethodName.equals(name))
                        {
                            throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "This field/method with name : " + fieldOrMethodName + " is already defined.");
                        }

                        else
                        {
                            configureFieldOrMethodMetaData(component, child);
                            fieldOrMethodName = name;

                            isElementApplicable = true;
                        }
                    }
                    else
                    {
                        configureFieldOrMethodMetaData(component, child);
                        fieldOrMethodName = name;

                        isElementApplicable = true;
                    }
                }
                else
                {
                    throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Parent and child namespace has to be the same for field/method element decleration");
                }
            }

            /* This element netiher constructor, annotation , field or method */
            if (!isElementApplicable)
            {
                throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Element with name : " + XMLUtil.getName(child) + " is not applicable for child of the simple webbeans class :  " + component.getReturnType().getName());
            }

        }// end of while

        // Check Annotation Types
        XMLDefinitionUtil.checkTypeMetaDataClasses(annotationSet, createConfigurationFailedMessage());

        // Configure type-level metadata
        configureTypeLevelMetaData(component, annotationSet, annotationElementList, webBeanDecleration);

        // Constructor decleration
        if (isConstructor)
        {
            // Configure constructor parameters
            configureConstructorMetaData(component, constTypeList, constructorParameterElementList);
        }
        else
        {
            // Default constructor
            component.setConstructor(WebBeansUtil.defineConstructor(component.getReturnType()));
        }

    }

    /**
     * Configures the type level meta data of the webbeans component.
     *
     * @param component xml webbeans component
     * @param annotationSet type level annotation set
     * @param webBeanDecleration webbeans decleration element
     */
    public <T> void configureTypeLevelMetaData(XMLManagedBean<T> component, List<Class<? extends Annotation>> annotationSet, List<Element> annotationElementList, Element webBeanDecleration)
    {
        boolean isInterceptor = false;
        boolean isDecorator = false;

        /* Check this is an Interceptor */
        if (annotationSet.contains(Interceptor.class))
        {
            isInterceptor = true;
        }

        /* Check this is a Decorator */
        if (annotationSet.contains(Decorator.class))
        {
            isDecorator = true;
        }

        // StereoType
        configureStereoType(component, annotationSet, annotationElementList);

        // Deployment Type
        configureDeploymentType(component, annotationSet, annotationElementList);

        // Scope Type
        configureScopeType(component, annotationSet, annotationElementList);

        // Binding Type
        configureBindingType(component, annotationSet, annotationElementList);

        if (!isInterceptor && !isDecorator)
        {
            // InterceptorBinding Type
            configureInterceptorBindingType(component, annotationSet, annotationElementList);
        }

        // Name configuration
        configureNamed(component, annotationSet, webBeanDecleration);

        // Specializations
        configureSpecializes(component, annotationSet);

        /* Interceptor Definition */
        if (isInterceptor)
        {
            configureInterceptor(component, annotationSet, annotationElementList);
        }

        /* Decorator Definition */
        if (isDecorator)
        {
            configureDecorator(component, annotationSet, annotationElementList, webBeanDecleration);
        }
    }

    /**
     * Configures the type level meta data of the webbeans component.
     *
     * @param component xml webbeans component
     * @param annotationSet type level annotation set
     * @param webBeanDecleration webbeans decleration element
     */
    public <T> void configureProducerTypeLevelMetaData(AbstractBean<T> component, List<Class<? extends Annotation>> annotationSet, List<Element> annotationElementList, Element webBeanDecleration)
    {
        configureBindingType(component, annotationSet, annotationElementList);

        // StereoType
        configureStereoType(component, annotationSet, annotationElementList);

        // Deployment Type
        configureDeploymentType(component, annotationSet, annotationElementList);

        // Scope Type
        configureScopeType(component, annotationSet, annotationElementList);

        // Name configuration
        configureNamed(component, annotationSet, webBeanDecleration);
    }

    /**
     * Configures the component constructor. When resolution dependency of the
     * constructor injection points, constructor parameter type defined in the
     * xml is used.
     *
     * @param component xml webbeans component
     * @param typeList list of the constructor parameter types
     * @param constructorParameterListElement parameter list element
     * @throws DefinitionException if more than one constructor exists
     * @throws NonexistentConstructorException if no constructor exists
     */
    private <T> void configureConstructorMetaData(XMLManagedBean<T> component, List<Class<?>> typeList, List<Element> constructorParameterListElement)
    {
        Class<T> implClazz = component.getReturnType();
        Constructor<T> cons[] = ClassUtil.getConstructors(implClazz);

        boolean found = false;
        Constructor<T> componentConstructor = null;
        for (Constructor<T> constructor : cons)
        {
            Class<?>[] pt = constructor.getParameterTypes();

            // same parameter size
            if (pt.length == typeList.size())
            {
                int j = 0;
                boolean ok = false;

                for (Class<?> parameterType : pt)
                {
                    Class<?> xmlType = typeList.get(j);

                    if (ClassUtil.isAssignable(parameterType, xmlType))
                    {
                        if (!ok)
                        {
                            ok = true;
                        }
                    }
                    else
                    {
                        ok = false;
                    }

                    j++;
                }

                if (ok)
                {
                    if (found)
                    {
                        throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "More than one constructor decleration exist.");
                    }
                    else
                    {
                        found = true;
                        componentConstructor = constructor;
                    }
                }

            }

        }

        if (!found)
        {
            throw new NonexistentConstructorException(createConfigurationFailedMessage() + "Constructor decleration not found in the class.");
        }

        XMLInjectableConstructor<T> injectableConstructor = new XMLInjectableConstructor<T>(componentConstructor, component,null);
        int i = 0;
        Constructor<?> constructor = injectableConstructor.getConstructor();
        for (Element element : constructorParameterListElement)
        {
            XMLInjectionPointModel model = XMLUtil.getInjectionPointModel(element, createConfigurationFailedMessage());
            injectableConstructor.addInjectionPointModel(model);
           
            Annotation[] paramAnnos = constructor.getParameterAnnotations()[i++];           
           
            for(Annotation paramAnno : paramAnnos)
            {
                model.addAnnotation(paramAnno);
            }
           
            model.setInjectionMember(constructor);
            model.setType(XMLInjectionModelType.CONSTRUCTOR);
         
            component.addInjectionPoint(InjectionPointFactory.getXMLInjectionPointData(component, model));
        }

        component.setInjectableConstructor(injectableConstructor);
    }

    /**
     * Configures the field or method of the xml webbeans component. Checks for
     * the field or method definition and call corresponding method.
     *
     * @param component xml webbeans component
     * @param child field or method child element
     */
    private <T> void configureFieldOrMethodMetaData(XMLManagedBean<T> component, Element child)
    {
        if (XMLUtil.isElementField(child))
        {
            configureField(component, child);

        }
        else if (XMLUtil.isElementMethod(child))
        {
            configureMethod(component, child);
        }
    }

    /**
     * Configures the given child element as field of the webbeans component.
     *
     * @param component xml webbeans component
     * @param child field element
     * @throws NonexistentFieldException if field not exist
     * @throws DefinitionException if field type declared in the xml is not
     *             assignable to the type declared in class
     * @throws DefinitionException if contains more than one &lt;valuegt;
     *             element childs
     */
    private <T> void configureField(XMLManagedBean<T> component, Element child)
    {
        Class<?> clazz = component.getReturnType();

        String fieldName = XMLUtil.getName(child);
        Field field = ClassUtil.getFieldWithName(clazz, fieldName);

        if (field == null)
        {
            throw new NonexistentFieldException(createConfigurationFailedMessage() + "Field name : " + fieldName + " decleration not found in the class : " + clazz.getName());
        }

        boolean isValueElement = false;

        boolean isApplicable = false;
        if (child.isTextOnly())
        {
            if (!isValueElement)
            {
                isValueElement = true;
                isApplicable = true;
            }
        }

        List<Element> directChilds = child.elements();
        Iterator<Element> itChilds = directChilds.iterator();

        boolean isTypeElement = false;

        // it has some other elements
        while (itChilds.hasNext())
        {
            Element directChild = itChilds.next();
            if (XMLUtil.isElementInWebBeansNameSpaceWithName(directChild, WebBeansConstants.WEB_BEANS_XML_VALUE_ELEMENT))
            {
                if (!isValueElement)
                {
                    isValueElement = true;
                    isApplicable = true;
                }

            }
            else
            {
                Class<?> directChildType = XMLUtil.getElementJavaType(directChild);
                if (!ClassUtil.isAssignable(field.getType(), directChildType))
                {
                    throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Declared field type is not assignable to class field type");
                }
                else
                {
                    XMLInjectionPointModel injectionPointModel = XMLUtil.getInjectionPointModel(directChild, createConfigurationFailedMessage());
                    component.addFieldInjectionPoint(field, injectionPointModel);
                   
                    Annotation[] annots = field.getAnnotations();
                    for(Annotation annotation : annots)
                    {
                        injectionPointModel.addAnnotation(annotation);
                    }
                   
                    injectionPointModel.setInjectionMember(field);
                    injectionPointModel.setType(XMLInjectionModelType.FIELD);
                    component.addInjectionPoint(InjectionPointFactory.getXMLInjectionPointData(component, injectionPointModel));

                    isTypeElement = true;
                    isApplicable = true;
                }
            }
        }

        if (!isApplicable)
        {
            throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Field with name : " + fieldName + " element is not correctly defined");
        }

        if (directChilds.size() > 1)
        {
            if (!isValueElement)
            {
                throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "One of the direct childs of the field must be element <value>");
            }
            else
            {
                if (isValueElement && isTypeElement)
                {
                    throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Direct child of the field can not contains both value element and type element");
                }
            }
        }

        // configure field values if available.
        configureFieldValues(component, field, child, isValueElement);

    }

    /**
     * Configures the method of the webbeans component.
     *
     * @param component xml webbeans component
     * @param child method element
     * @throws NonexistentMethodException if method with name does not exist
     * @throws NonexistentTypeException if method parameter types can not found
     * @throws DefinitionException if any other configuration related exception
     *             occurs.
     */
    private <T> void configureMethod(XMLManagedBean<T> component, Element child)
    {
        if (!ClassUtil.isMethodExistWithName(component.getReturnType(), XMLUtil.getName(child)))
        {
            throw new NonexistentMethodException(createConfigurationFailedMessage() + "Method declaration with name " + XMLUtil.getName(child) + " is not found in the class : " + component.getReturnType().getName());
        }

        List<Element> methodChilds = child.elements();
        Iterator<Element> itMethodChilds = methodChilds.iterator();

        boolean isDefineType = false;

        /*
         * <Initializes> = 0; <Produces> = 1; <Disposes> = 2; <Observes> = 3;
         * <Destructor> = 4; InterceptorBindingType annotation on method = 5;
         */
        int type = 0;

        /* Method parameters classes */
        List<Class<?>> methodParameters = new ArrayList<Class<?>>();

        /* Method parameter xml elements */
        List<Element> methodParameterElements = new ArrayList<Element>();

        Element methodChild = null;

        while (itMethodChilds.hasNext())
        {
            methodChild = itMethodChilds.next();
            Class<?> childClazz = XMLUtil.getElementJavaType(methodChild);

            final String moreThanOneChildTypeErrorMesg = createConfigurationFailedMessage() + XMLUtil.getName(methodChild) + "method declaration can not contain more than one <Initializer>, <Destructor>, <Produces>, <Disposes> or <Observes> element";

            if (childClazz == null)
            {
                throw new NonexistentTypeException(createConfigurationFailedMessage() + "Direct child element of method : " + XMLUtil.getName(methodChild) + " does not corresponds to any Java type");
            }
            else
            {
                if (childClazz.isAnnotation())
                {
                    if (childClazz.equals(Disposes.class))
                    {
                        if (isDefineType)
                        {
                            throw new WebBeansConfigurationException(moreThanOneChildTypeErrorMesg);
                        }
                        else
                        {
                            checkConfigureDisposes(component, methodChild);
                            isDefineType = true;
                            type = 2;
                        }

                    }
                    else if (childClazz.equals(Observes.class))
                    {
                        if (isDefineType)
                        {
                            throw new WebBeansConfigurationException(moreThanOneChildTypeErrorMesg);
                        }
                        else
                        {
                            checkConfigureObserves(component, methodChild);
                            isDefineType = true;
                            type = 3;
                        }
                    }
                    else if (childClazz.equals(Inject.class))
                    {
                        if (isDefineType)
                        {
                            throw new WebBeansConfigurationException(moreThanOneChildTypeErrorMesg);
                        }
                        else
                        {
                            isDefineType = true;
                            type = 0;
                        }

                    }
                    else if (childClazz.equals(Produces.class))
                    {
                        if (isDefineType)
                        {
                            throw new WebBeansConfigurationException(moreThanOneChildTypeErrorMesg);
                        }
                        else
                        {
                            isDefineType = true;
                            type = 1;
                        }
                    }
                    else if (AnnotationUtil.isInterceptorBindingAnnotation((Class<? extends Annotation>) childClazz))
                    {
                        // InterceptorBindingType with method
                        type = 5;
                    }
                    else
                    {
                        throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Direct child element of method : " + XMLUtil.getName(methodChild) + " with Java type : " + childClazz + " is unknown");
                    }
                }
                // Method parameter
                else
                {
                    methodParameters.add(childClazz);
                    methodParameterElements.add(methodChild);
                }
            }
        }

        // Check method conditions with method name and its parameter types.
        Method annotatedMethod = checkConfigureMethodConditions(component, child, methodParameters);

        // Configures method according to the type of the element in 0,1,2,3,4,5
        configureMethodAnnotationType(component, annotatedMethod, child, type, methodParameterElements);

    }

    /**
     * Configures the webbeans component methods that are defines in the xml.
     *
     * @param component xml webbeans component
     * @param annotatedMethod annotated method to configure
     * @param annotChild element child
     * @param type type of the configuration method
     */
    private <T> void configureMethodAnnotationType(XMLManagedBean<T> component, Method annotatedMethod, Element annotChild, int type, List<Element> methodParameterElements)
    {
        switch (type)
        {
        case 0:

            configureMethodInitializeAnnotation(component, annotatedMethod, methodParameterElements);
            break;

        case 1:
            configureMethodProducesAnnotation(component, annotatedMethod, annotChild);
            break;

        case 2:
            configureMethodDisposesAnnotation(component, annotatedMethod, annotChild);
            break;

        case 3:
            configureMethodObservesAnnotation(component, annotatedMethod, annotChild);
            break;

        case 5:
            configureMethodInterceptorBindingTypeAnnotation(component, annotatedMethod, annotChild);
            break;
        }
    }

    /**
     * Configures the initializor method of the webbeans component.
     *
     * @param component xml webbeans component
     * @param initializeMethod initialize method of the webbeans component
     * @param annotChild element child
     */
    private <T> void configureMethodInitializeAnnotation(XMLManagedBean<T> component, Method initializeMethod, List<Element> methodParameterElements)
    {
        if (methodParameterElements.isEmpty())
        {
            component.addMethodInjectionPoint(initializeMethod, null);
        }
        else
        {
            for (Element element : methodParameterElements)
            {
                XMLInjectionPointModel model = XMLUtil.getInjectionPointModel(element, createConfigurationFailedMessage());
                component.addMethodInjectionPoint(initializeMethod, model);
               
                component.addInjectionPoint(XMLDefinitionUtil.getXMLMethodInjectionPoint(component, model, initializeMethod));
            }
        }
    }

    private <T> void configureMethodProducesAnnotation(XMLManagedBean<T> component, Method producesMethod, Element annotChild)
    {
        XMLProducerBean<T> producer = XMLDefinitionUtil.defineXMLProducerMethod(this, component, producesMethod, annotChild, createConfigurationFailedMessage());
        BeanManagerImpl.getManager().addBean(producer);
    }

    private <T> void configureMethodDisposesAnnotation(XMLManagedBean<T> component, Method disposalMethod, Element annotChild)
    {
        XMLDefinitionUtil.defineXMLDisposalMethod(component, disposalMethod, annotChild, createConfigurationFailedMessage());

    }

    private <T> void configureMethodObservesAnnotation(XMLManagedBean<T> component, Method observesMethod, Element annotChild)
    {
        XMLDefinitionUtil.defineXMLObservesMethod(component, observesMethod, annotChild, createConfigurationFailedMessage());
    }

    private <T> void configureMethodInterceptorBindingTypeAnnotation(XMLManagedBean<T> component, Method interceptorMethod, Element annotChild)
    {
        XMLDefinitionUtil.defineXMLMethodLevelInterceptorType(component, interceptorMethod, annotChild, createConfigurationFailedMessage());
    }

    /**
     * Check method conditions for the webbeans component.
     *
     * @param component xml webbeans component
     * @param child method element
     * @param methodParameters method parameter types
     * @throws NonexistentMethodException if no method is exist with given name
     *             and method parameter types
     * @throws DefinitionException if more than one method satisfies the
     *             conditions
     */
    private <T> Method checkConfigureMethodConditions(XMLManagedBean<T> component, Element child, List<Class<?>> methodParameters)
    {
        // Check with name and also parameter types
        List<Method> definedMethods = ClassUtil.getClassMethodsWithTypes(component.getReturnType(), XMLUtil.getName(child), methodParameters);

        if (definedMethods.size() == 0)
        {
            throw new NonexistentMethodException(createConfigurationFailedMessage() + "Method declaration with name " + XMLUtil.getName(child) + " is not found in the class : " + component.getReturnType().getName());

        }
        else if (definedMethods.size() > 1)
        {
            throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "More than one method : " + XMLUtil.getName(child) + " is found in the class : " + component.getReturnType().getName());
        }

        return definedMethods.get(0);
    }

    /**
     * Configures the disposal method of the webbeans component.
     *
     * @param component xml webbeans component
     * @param disposes disposes element
     * @throws DefinitionException if disposes element can not contain exactly
     *             one child element
     */
    private <T> void checkConfigureDisposes(AbstractBean<T> component, Element disposes)
    {
        List<Element> disposesChilds = disposes.elements();

        if (disposesChilds.size() != 1)
        {
            throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Disposes element : " + XMLUtil.getName(disposes) + " can not contain more than one direct child elements");
        }

    }

    /**
     * Configures the observer method of the webbeans component
     *
     * @param component xml webbeans component
     * @param observes observes element
     * @throws DefinitionException if disposes element can not contain exactly
     *             one child element and it is not one of the {IfExists,
     *             AfterTransactionCompletion, AfterTransactionSuccess,
     *             AfterTransactionFailure, BeforeTransactionCompletion}
     *             element.
     */
    private <T> void checkConfigureObserves(AbstractBean<T> component, Element observes)
    {
        List<Element> observesChilds = observes.elements();

        if (observesChilds.size() != 1)
        {
            throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Observes element : " + XMLUtil.getName(observes) + " can not contain more than one direct child elements");
        }
        else
        {
//            Element child = observesChilds.iterator().next();
//            Class<?> clazz = XMLUtil.getElementJavaType(child);

//            if ((clazz == null) || clazz.equals(IfExists.class) || clazz.equals(AfterTransactionCompletion.class) || clazz.equals(AfterTransactionSuccess.class) || clazz.equals(AfterTransactionFailure.class) || clazz.equals(BeforeTransactionCompletion.class))
//            {
//                throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Observes element : " + XMLUtil.getName(observes) + " must not have one of the {<IfExists>, <AfterTransactionCompletion>, <AfterTransactionSuccess>, <AfterTransactionFailure>, <BeforeTransactionCompletion>} as a direct child.");
//            }
        }

    }

    /**
     * Configures the deployment type of the XML component.
     *
     * @param component xml defined web beans component
     * @param annotationSet all annotation defined in XML
     */
    private <T> void configureDeploymentType(AbstractBean<T> component, List<Class<? extends Annotation>> annotationSet, List<Element> annotationElementList)
    {
        Class<? extends Annotation> deploymentType = XMLDefinitionUtil.defineXMLTypeMetaData(component, annotationSet, DeploymentType.class, createConfigurationFailedMessage() + "@DeploymentType annotation is not configured correctly for class : " + component.getReturnType().getName());

        if (deploymentType == null)
        {
            // Check from stereotype
            Annotation stereoTypeDeploymentType = WebBeansUtil.getMaxPrecedenceSteroTypeDeploymentType(component);
           
            if(stereoTypeDeploymentType == null)
            {
                // Default deployment type
                component.setType(new ProductionLiteral());               
            }
            else
            {
                component.setType(stereoTypeDeploymentType);
            }
           
        }
        else
        {
            component.setType(JavassistProxyFactory.createNewAnnotationProxy(deploymentType));
        }
    }

    /**
     * Configures the webbeans scope type.
     *
     * @param component xml defined web beans component
     * @param annotationSet all annotation defined in XML
     */
    private <T> void configureScopeType(AbstractBean<T> component, List<Class<? extends Annotation>> annotationSet, List<Element> annotationElementList)
    {
        Class<? extends Annotation> scopeType = XMLDefinitionUtil.defineXMLTypeMetaData(component, annotationSet, NormalScope.class, createConfigurationFailedMessage() + "@Scope/@NormalScope annotation is not configured correctly");

        if(scopeType == null)
        {
            scopeType = XMLDefinitionUtil.defineXMLTypeMetaData(component, annotationSet, Scope.class, createConfigurationFailedMessage() + "@Scope/@NormalScope annotation is not configured correctly");           
        }
       
        if (scopeType == null)
        {
            // From stereotype
            DefinitionUtil.defineDefaultScopeType(component, createConfigurationFailedMessage() + "@Scope annotation is not configured correctly");
        }
        else
        {
            component.setImplScopeType(JavassistProxyFactory.createNewAnnotationProxy(scopeType));
        }

    }

    /**
     * Configures the binding types of the web beans component.
     *
     * @param component web beans xml component
     * @param anns annotations defined in the xml documents
     */
    private <T> void configureBindingType(AbstractBean<T> component, List<Class<? extends Annotation>> annotationSet, List<Element> annotationElementList)
    {
        boolean isDefined = XMLDefinitionUtil.defineXMLBindingType(component, annotationSet, annotationElementList, createConfigurationFailedMessage());

        if (!isDefined)
        {
            component.addQualifier(new CurrentLiteral());
        }

    }

    /**
     * Configures the class level interceptor binding types.
     *
     * @param component web beans xml component
     * @param anns annotations defined in the xml documents
     */
    private <T> void configureInterceptorBindingType(XMLManagedBean<T> component, List<Class<? extends Annotation>> annotationSet, List<Element> annotationElementList)
    {
        XMLDefinitionUtil.defineXMLClassLevelInterceptorType(component, annotationSet, annotationElementList, createConfigurationFailedMessage());
    }

    /**
     * Defines the component stereotypes.
     *
     * @param component webbeans component
     * @param annotationSet type-level metadata annotation set
     */
    private <T> void configureStereoType(AbstractBean<T> component, List<Class<? extends Annotation>> annotationSet, List<Element> annotationElementList)
    {
        XMLDefinitionUtil.defineXMLStereoType(component, annotationSet);
    }

    /**
     * Configures the webbeans name.
     *
     * @param component webbeans component
     * @param annotationSet type-level metadata annotation set
     * @param webBeanDecleration webbeans decleration element
     */
    private <T> void configureNamed(AbstractBean<T> component, List<Class<? extends Annotation>> annotationSet, Element webBeanDecleration)
    {
        boolean isDefined = XMLDefinitionUtil.defineXMLName(component, annotationSet);
        if (isDefined)
        {
            Element element = webBeanDecleration.element(WebBeansConstants.WEB_BEANS_XML_NAMED_ELEMENT);
            String name = element.getTextTrim();

            if (name != null && !name.equals(""))
            {
                component.setName(name);
            }
            else
            {
                component.setName(WebBeansUtil.getSimpleWebBeanDefaultName(component.getReturnType().getName()));
            }
        }
        else
        {
            DefinitionUtil.defineName(component, component.getReturnType().getDeclaredAnnotations(), WebBeansUtil.getSimpleWebBeanDefaultName(component.getReturnType().getSimpleName()));
        }
    }

    /**
     * Configures the webbeans specializations.
     *
     * @param component webbeans component
     * @param annotationSet type-level metadata annotation set
     */
    private <T> void configureSpecializes(XMLManagedBean<T> component, List<Class<? extends Annotation>> annotationSet)
    {
        XMLDefinitionUtil.defineXMLSpecializes(component, annotationSet);
    }

    /**
     * Configures the interceptors simple webbeans.
     *
     * @param component webbeans component
     * @param annotationSet type-level metadata annotation set
     */
    private <T> void configureInterceptor(XMLManagedBean<T> component, List<Class<? extends Annotation>> annotationSet, List<Element> annotationElementList)
    {
        XMLDefinitionUtil.defineXMLInterceptors(component, annotationSet, annotationElementList, createConfigurationFailedMessage());

    }

    /**
     * Configures the decorators simple webbeans.
     *
     * @param component webbeans component
     * @param annotationSet type-level metadata annotation set
     */
    private <T> void configureDecorator(XMLManagedBean<T> component, List<Class<? extends Annotation>> annotationSet, List<Element> annotationElementList, Element webBeanDecleration)
    {
        XMLDefinitionUtil.defineXMLDecorators(component, annotationSet, webBeanDecleration, createConfigurationFailedMessage());
    }

    /**
     * Configures the enterprise web bean from ejb class.
     *
     * @param ejbClass ejb class
     */
    private void configureEJBWebBean(Class<?> ejbClass)
    {
        // TODO EJB Decleration
    }

    /**
     * Configures JMS endpoint.
     *
     * @param webBeanElement element
     */
    private void configureJMSEndpointComponent(Element webBeanElement)
    {
        List<Element> childs = webBeanElement.elements();              
        Element resource = webBeanElement.element(WebBeansConstants.WEB_BEANS_XML_JMS_RESOURCE);
       
        if(resource == null)
        {
            throw new WebBeansConfigurationException("Topic or Queue resource mut be defined in the XML");
        }

        Element name = resource.element(WebBeansConstants.WEB_BEANS_XML_JMS_RESOURCE_NAME);
        Element mappedName = resource.element(WebBeansConstants.WEB_BEANS_XML_JMS_RESOURCE_MAPPED_NAME);
       
        if(name== null && mappedName == null)
        {
            throw new WebBeansConfigurationException("Topic or Queue must define name or mapped name for the JNDI");
        }
       
        List<Annotation> bindingTypes = new ArrayList<Annotation>();
        for(Element child : childs)
        {
            if(child.getName() != WebBeansConstants.WEB_BEANS_XML_JMS_RESOURCE)
            {
                Class<? extends Annotation> binding = (Class<Annotation>)XMLUtil.getElementJavaType(child);
               
                if(AnnotationUtil.isQualifierAnnotation(binding))
                {
                    bindingTypes.add(JavassistProxyFactory.createNewAnnotationProxy(binding));               
                }               
            }           
        }
                       
        JMSType type = null;
       
        if(webBeanElement.getName().equals(WebBeansConstants.WEB_BEANS_XML_TOPIC_ELEMENT))
        {
            type = JMSType.TOPIC;
        }
        else
        {
            type = JMSType.QUEUE;
        }
       
       
        String jndiName = name == null ? null : name.getTextTrim();
        String mapName = mappedName== null ? null : mappedName.getTextTrim();
       
       
        JMSModel model = new JMSModel(type,jndiName,mapName);       
        JMSManager.getInstance().addJmsModel(model);
       
        for(Annotation ann : bindingTypes)
        {
            model.addBinding(ann);
        }
       
        //Adding JMS Beans
        OpenWebBeansJmsPlugin plugin = PluginLoader.getInstance().getJmsPlugin();
        BeanManagerImpl.getManager().addBean(plugin.getJmsBean(model));
    }

    /**
     * Cofigures the initial value of the given field.
     *
     * @param component webbeans component
     * @param field field of the webbean
     * @param child child element that declares field
     * @param isValueElement is it applicable for value setting
     */
    private <T> void configureFieldValues(XMLManagedBean<T> component, Field field, Element child, boolean isValueElement)
    {
        if (isValueElement)
        {
            String errorMessage = createConfigurationFailedMessage() + "Field value of field name : " + field.getName() + " is not applicable for initial value assignment";

            /* Field type */
            Class<?> fieldType = field.getType();

            String value = child.getTextTrim();

            try
            {

                if (!ClassUtil.isInValueTypes(fieldType))
                {
                    throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Field type with field name : " + field.getName() + " is not compatible for initial value assignment");
                }
               
                /*Primitive type*/
                if (ClassUtil.isPrimitive(fieldType) || ClassUtil.isPrimitiveWrapper(fieldType))
                {
                    Object objVal = null;

                    if ((objVal = ClassUtil.isValueOkForPrimitiveOrWrapper(fieldType, value)) != null)
                    {
                        component.addFieldValue(field, objVal);

                    }
                    else
                    {
                        throw new WebBeansConfigurationException(errorMessage);
                    }

                }
                /* Enumeration value */
                else if (ClassUtil.isEnum(fieldType))
                {
                    Enum enumValue = ClassUtil.isValueOkForEnum(fieldType, value);

                    if (enumValue == null)
                    {
                        throw new WebBeansConfigurationException(errorMessage);
                    }

                    component.addFieldValue(field, enumValue);

                }
                /* String value */
                else if (fieldType.equals(String.class))
                {
                    component.addFieldValue(field, value);

                }
               
                /*
                 * Date, Time, Sql Date,
                 * Time stamp, Calendar
                 * value
                 */               
                else if (fieldType.equals(Date.class)
                        || fieldType.equals(java.sql.Date.class) || fieldType.equals(Time.class) || fieldType.equals(Timestamp.class))
                {
                    Date date = ClassUtil.isValueOkForDate(value);

                    if (date == null)
                    {
                        throw new WebBeansConfigurationException(errorMessage);
                    }
                    else
                    {
                        component.addFieldValue(field, date);
                    }

                }
                else if (fieldType.equals(Calendar.class))
                {
                    Calendar calendar = ClassUtil.isValueOkForCalendar(value);

                    if (calendar == null)
                    {
                        throw new WebBeansConfigurationException(errorMessage);
                    }
                    else
                    {
                        component.addFieldValue(field, calendar);
                    }

                }
                /*
                 * BigDecimal
                 * or
                 * BigInteger
                 */               
                else if (fieldType.equals(BigDecimal.class) || fieldType.equals(BigInteger.class))
                {
                    Object bigValue = ClassUtil.isValueOkForBigDecimalOrInteger(fieldType, value);

                    if (bigValue == null)
                    {
                        throw new WebBeansConfigurationException(errorMessage);
                    }
                    else
                    {
                        component.addFieldValue(field, bigValue);
                    }

                }
                /* Class value */
                else if (fieldType.equals(Class.class))
                {
                    Class<?> clazz = ClassUtil.getClassFromName(value);

                    if (clazz == null)
                    {
                        throw new WebBeansConfigurationException(errorMessage);
                    }
                    else
                    {
                        component.addFieldValue(field, clazz);
                    }
                }
               
                /*
                 * List value
                 */
                else if (List.class.isAssignableFrom(fieldType))
                {
                    configureFieldListValue(component, field, child, errorMessage);
                }
               
                /* Set value */
                else if (Set.class.isAssignableFrom(fieldType))
                {
                    configureFieldSetValue(component, field, child, errorMessage);
                }

            }
            catch (ParseException e)
            {
                throw new WebBeansConfigurationException(errorMessage, e);
            }
        }
    }

    /**
     * Configures the xml field with {@link List} type.
     *
     * @param component xml component
     * @param field list field
     * @param child list field xml element
     * @param errorMessage error message
     */
    private void configureFieldListValue(XMLManagedBean<?> component, Field field, Element child, String errorMessage)
    {
        boolean isString = false;
        boolean isEnum = false;
        boolean isClazz = false;
        Type type = field.getGenericType();
        Class<?> argClazz = null;
        List list = null;

        /*
         * Type must be parametrized type
         * to mark type
         */       
        if (type instanceof ParameterizedType)
        {
            ParameterizedType pt = (ParameterizedType) type;
            Type arg = pt.getActualTypeArguments()[0];

            if (ClassUtil.isFirstParametricTypeArgGeneric(pt))
            {
                throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "List field type with field name : " + field.getName() + " must be declared as ParametrizedType " + "but parametric type can not be TypeVariable or Wildcard Type");
            }

            else
            {
                argClazz = (Class<?>) arg;

                if (argClazz.equals(String.class))
                {
                    isString = true;
                    list = new ArrayList<String>();
                }
                else if (Enum.class.isAssignableFrom(argClazz))
                {
                    isEnum = true;
                    list = new ArrayList<Enum>();
                }
                else if (argClazz.equals(Class.class))
                {
                    isClazz = true;
                    list = new ArrayList<Class>();
                }
            }
        }
        else
        {
            throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "List field type with field name : " + field.getName() + " must be declared as ParametrizedType");
        }

        List<Element> valueElements = child.elements();
        for (Element valueElement : valueElements)
        {
            String value = valueElement.getTextTrim();
            if (isString)
            {
                list.add(value);
            }
            else if (isEnum)
            {
                Enum en = ClassUtil.isValueOkForEnum(argClazz, value);
                if (en == null)
                {
                    throw new WebBeansConfigurationException(errorMessage);
                }
                else
                {
                    list.add(en);
                }
            }
            else if (isClazz)
            {
                Class<?> clazz = ClassUtil.getClassFromName(value);

                if (clazz == null)
                {
                    throw new WebBeansConfigurationException(errorMessage);
                }
                else
                {
                    list.add(clazz);
                }
            }
        }

        component.addFieldValue(field, list);
    }

    /**
     * Configures the xml field with {@link Set} type.
     *
     * @param component xml component
     * @param field list field
     * @param child list field xml element
     * @param errorMessage error message
     */
    private void configureFieldSetValue(XMLManagedBean<?> component, Field field, Element child, String errorMessage)
    {
        boolean isString = false;
        boolean isEnum = false;
        boolean isClazz = false;
        Type type = field.getGenericType();
        Class<?> argClazz = null;
        Set set = null;

        /*
         * Type must be parametrized type
         * to mark type
         */       
        if (type instanceof ParameterizedType)
        {
            ParameterizedType pt = (ParameterizedType) type;
            Type arg = pt.getActualTypeArguments()[0];

            if (ClassUtil.isFirstParametricTypeArgGeneric(pt))
            {
                throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Set field type with field name : " + field.getName() + " must be declared as ParametrizedType " + "but parametric type can not be TypeVariable or Wildcard Type");
            }

            else
            {
                argClazz = (Class<?>) arg;

                if (argClazz.equals(String.class))
                {
                    isString = true;
                    set = new HashSet<String>();
                }
                else if (Enum.class.isAssignableFrom(argClazz))
                {
                    isEnum = true;
                    set = new HashSet<Enum>();
                }
                else if (argClazz.equals(Class.class))
                {
                    isClazz = true;
                    set = new HashSet<Class>();
                }
            }
        }
        else
        {
            throw new WebBeansConfigurationException(createConfigurationFailedMessage() + "Set field type with field name : " + field.getName() + " must be declared as ParametrizedType");
        }

        List<Element> valueElements = child.elements();
        for (Element valueElement : valueElements)
        {
            String value = valueElement.getTextTrim();
            if (isString)
            {
                set.add(value);
            }
            else if (isEnum)
            {
                Enum en = ClassUtil.isValueOkForEnum(argClazz, value);
                if (en == null)
                {
                    throw new WebBeansConfigurationException(errorMessage);
                }
                else
                {
                    set.add(en);
                }
            }
            else if (isClazz)
            {
                Class<?> clazz = ClassUtil.getClassFromName(value);

                if (clazz == null)
                {
                    throw new WebBeansConfigurationException(errorMessage);
                }
                else
                {
                    set.add(clazz);
                }
            }
        }

        component.addFieldValue(field, set);
    }

    /**
     * Gets error message for XML parsing of the current XML file.
     *
     * @return the error messages
     */
    private String createConfigurationFailedMessage()
    {
        return "WebBeans XML configuration defined in " + CURRENT_SCAN_FILE_NAME + " is failed. Reason is : ";
    }

}
TOP

Related Classes of org.apache.webbeans.xml.WebBeansXMLConfigurator

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.