Package org.apache.openejb.cdi

Source Code of org.apache.openejb.cdi.BeansDeployer

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

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.Stack;

import javax.enterprise.inject.Model;
import javax.enterprise.inject.Specializes;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.Decorator;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.interceptor.Interceptor;

import org.apache.webbeans.annotation.AnnotationManager;
import org.apache.webbeans.component.AbstractInjectionTargetBean;
import org.apache.webbeans.component.AbstractProducerBean;
import org.apache.webbeans.component.EnterpriseBeanMarker;
import org.apache.webbeans.component.InjectionTargetBean;
import org.apache.webbeans.component.InjectionTargetWrapper;
import org.apache.webbeans.component.InterceptedMarker;
import org.apache.webbeans.component.ManagedBean;
import org.apache.webbeans.component.NewBean;
import org.apache.webbeans.component.OwbBean;
import org.apache.webbeans.component.WebBeansType;
import org.apache.webbeans.component.creation.BeanCreator.MetaDataProvider;
import org.apache.webbeans.component.creation.ManagedBeanCreatorImpl;
import org.apache.webbeans.config.DefinitionUtil;
import org.apache.webbeans.config.OWBLogConst;
import org.apache.webbeans.config.WebBeansContext;
import org.apache.webbeans.container.BeanManagerImpl;
import org.apache.webbeans.container.InjectionResolver;
import org.apache.webbeans.decorator.WebBeansDecorator;
import org.apache.webbeans.deployment.StereoTypeModel;
import org.apache.webbeans.exception.WebBeansConfigurationException;
import org.apache.webbeans.exception.WebBeansDeploymentException;
import org.apache.webbeans.exception.inject.InconsistentSpecializationException;
import org.apache.webbeans.intercept.webbeans.WebBeansInterceptor;
import org.apache.webbeans.logger.WebBeansLogger;
import org.apache.webbeans.portable.events.ProcessAnnotatedTypeImpl;
import org.apache.webbeans.portable.events.ProcessInjectionTargetImpl;
import org.apache.webbeans.portable.events.discovery.AfterBeanDiscoveryImpl;
import org.apache.webbeans.portable.events.discovery.AfterDeploymentValidationImpl;
import org.apache.webbeans.portable.events.discovery.BeforeBeanDiscoveryImpl;
import org.apache.webbeans.spi.ScannerService;
import org.apache.webbeans.spi.plugins.OpenWebBeansJavaEEPlugin;
import org.apache.webbeans.spi.plugins.OpenWebBeansWebPlugin;
import org.apache.webbeans.util.AnnotationUtil;
import org.apache.webbeans.util.ClassUtil;
import org.apache.webbeans.util.WebBeansUtil;
import org.apache.webbeans.xml.WebBeansXMLConfigurator;

/**
* @version $Rev$ $Date$
*/

/**
* Deploys the all beans that are defined in the {@link org.apache.webbeans.spi.ScannerService} at
* the scanner phase.
*/
@SuppressWarnings("unchecked")
//This class written as single threaded.
public class BeansDeployer {
    //Logger instance
    private static final WebBeansLogger logger = WebBeansLogger.getLogger(BeansDeployer.class);

    /**XML Configurator*/
    protected final WebBeansXMLConfigurator xmlConfigurator;

    private final WebBeansContext webBeansContext;

    public BeansDeployer(WebBeansXMLConfigurator xmlConfigurator, WebBeansContext webBeansContext) {
        this.xmlConfigurator = xmlConfigurator;
        this.webBeansContext = webBeansContext;
    }

    /**
     * Configure Default Beans.
     */
    void configureDefaultBeans()
    {
        BeanManagerImpl beanManager = webBeansContext.getBeanManagerImpl();
        WebBeansUtil webBeansUtil = webBeansContext.getWebBeansUtil();

        // Register Manager built-in component
        beanManager.addInternalBean(webBeansUtil.getManagerBean());

        // Register Conversation built-in component
        beanManager.addBean(webBeansUtil.getConversationBean());

        // Register InjectionPoint bean
        beanManager.addBean(webBeansUtil.getInjectionPointBean());

        //Register Instance Bean
        beanManager.addBean(webBeansUtil.getInstanceBean());

        //Register Event Bean
        beanManager.addBean(webBeansUtil.getEventBean());

        //Register Provider Beans
        addDefaultBean(beanManager, "org.apache.webbeans.ee.common.beans.PrincipalBean");
        addDefaultBean(beanManager, "org.apache.webbeans.ee.beans.ValidatorBean");
        addDefaultBean(beanManager, "org.apache.webbeans.ee.beans.ValidatorFactoryBean");
        addDefaultBean(beanManager, "org.apache.webbeans.ee.beans.UserTransactionBean");
    }

    private void addDefaultBean(BeanManagerImpl manager,String className)
    {
        Bean<?> bean = null;

        Class<?> beanClass = ClassUtil.getClassFromName(className);
        if (beanClass != null) {
            bean = (Bean) ClassUtil.newInstance(webBeansContext, beanClass);
        }

        if (bean != null) {
            manager.addBean(bean);
        }
    }

    /**
     * Fires event before bean discovery.
     */
    void fireBeforeBeanDiscoveryEvent()
    {
        BeanManager manager = webBeansContext.getBeanManagerImpl();
        manager.fireEvent(new BeforeBeanDiscoveryImpl(webBeansContext),new Annotation[0]);
    }

    /**
     * Fires event after bean discovery.
     */
    void fireAfterBeanDiscoveryEvent()
    {
        BeanManagerImpl manager = webBeansContext.getBeanManagerImpl();
        manager.fireEvent(new AfterBeanDiscoveryImpl(webBeansContext),new Annotation[0]);

        webBeansContext.getWebBeansUtil().inspectErrorStack("There are errors that are added by AfterBeanDiscovery event observers. Look at logs for further details");
    }

    /**
     * Fires event after deployment valdiation.
     */
    void fireAfterDeploymentValidationEvent()
    {
        BeanManagerImpl manager = webBeansContext.getBeanManagerImpl();
        manager.fireEvent(new AfterDeploymentValidationImpl(manager),new Annotation[0]);

        webBeansContext.getWebBeansUtil().inspectErrorStack("There are errors that are added by AfterDeploymentValidation event observers. Look at logs for further details");
    }

    /**
     * Validate all injection points.
     */
    void validateInjectionPoints()
    {
        logger.debug("Validation of injection points has started.");

        webBeansContext.getDecoratorsManager().validateDecoratorClasses();
        webBeansContext.getInterceptorsManager().validateInterceptorClasses();

        BeanManagerImpl manager = webBeansContext.getBeanManagerImpl();
        Set<Bean<?>> beans = new HashSet<Bean<?>>();

        //Adding decorators to validate
        Set<Decorator<?>> decorators = manager.getDecorators();
        for (Decorator decorator : decorators) {
            WebBeansDecorator wbDec = (WebBeansDecorator) decorator;
            beans.add(wbDec);
        }


        logger.debug("Validation of the decorator's injection points has started.");

        //Validate Decorators
        validate(beans);

        beans.clear();

        //Adding interceptors to validate
        for (javax.enterprise.inject.spi.Interceptor<?> interceptor : manager.getInterceptors()) {
            WebBeansInterceptor wbInt = (WebBeansInterceptor) interceptor;
            beans.add(wbInt);
        }

        logger.debug("Validation of the interceptor's injection points has started.");

        //Validate Interceptors
        validate(beans);

        beans.clear();

        beans = manager.getBeans();

        //Validate Others
        validate(beans);

        logger.info(OWBLogConst.INFO_0003);
    }

    /**
     * Validates beans.
     *
     * @param beans deployed beans
     */
    private void validate(Set<Bean<?>> beans)
    {
        BeanManagerImpl manager = webBeansContext.getBeanManagerImpl();

        if (beans != null && beans.size() > 0) {
            Stack<String> beanNames = new Stack<String>();
            for (Bean<?> bean : beans) {
                String beanName = bean.getName();
                if (beanName != null) {
                    beanNames.push(beanName);
                }


                if (bean instanceof InjectionTargetBean) {
                    //Decorators not applied to interceptors/decorators/@NewBean
                    if (!(bean instanceof Decorator) &&
                            !(bean instanceof javax.enterprise.inject.spi.Interceptor) &&
                            !(bean instanceof NewBean)) {
                        new DefinitionUtil(webBeansContext).defineDecoratorStack((AbstractInjectionTargetBean<Object>) bean);
                    }

                    //If intercepted marker
                    if (bean instanceof InterceptedMarker) {
                      new DefinitionUtil(webBeansContext).defineBeanInterceptorStack((AbstractInjectionTargetBean<Object>) bean);
                    }
                }

                //Check passivation scope
                checkPassivationScope(bean);

                //Bean injection points
                Set<InjectionPoint> injectionPoints = bean.getInjectionPoints();

                //Check injection points
                if (injectionPoints != null) {
                    for (InjectionPoint injectionPoint : injectionPoints) {
                        if (!injectionPoint.isDelegate()) {
                            manager.validate(injectionPoint);
                        } else {
                            if (!bean.getBeanClass().isAnnotationPresent(javax.decorator.Decorator.class)
                                    && !webBeansContext.getBeanManagerImpl().containsCustomDecoratorClass(bean.getBeanClass())) {
                                throw new WebBeansConfigurationException(
                                        "Delegate injection points can not defined by beans that are not decorator. Injection point : "
                                                + injectionPoint);
                            }
                        }
                    }
                }
            }

            //Validate Bean names
            validateBeanNames(beanNames);

            //Clear Names
            beanNames.clear();
        }

    }

    private void validateBeanNames(Stack<String> beanNames)
    {
        if(beanNames.size() > 0)
        {
            for(String beanName : beanNames)
            {
                for(String other : beanNames)
                {
                    String part = null;
                    int i = beanName.lastIndexOf('.');
                    if (i != -1) {
                        part = beanName.substring(0, i);
                    }

                    if (beanName.equals(other)) {
                        InjectionResolver resolver = webBeansContext.getBeanManagerImpl().getInjectionResolver();
                        Set<Bean<?>> beans = resolver.implResolveByName(beanName);
                        if (beans.size() > 1) {
                            beans = resolver.findByAlternatives(beans);
                            if (beans.size() > 1) {
                                throw new WebBeansConfigurationException("There are two different beans with name : " + beanName + " in the deployment archieve");
                            }
                        }
                    } else {
                        if (part != null) {
                            if (part.equals(other)) {
                                throw new WebBeansConfigurationException("EL name of one bean is of the form x.y, where y is a valid bean EL name, and " +
                                        "x is the EL name of the other bean for the bean name : " + beanName);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * Discovers and deploys classes from XML.
     *
     * NOTE : Currently XML file is just used for configuring.
     *
     * @param scanner discovery scanner
     * @throws WebBeansDeploymentException if exception
     */
    protected void deployFromXML(ScannerService scanner) throws WebBeansDeploymentException
    {
    }
    /**
     * Checks specialization.
     * @param scanner scanner instance
     */
    protected void checkSpecializations(ScannerService scanner)
    {
        logger.debug("Checking Specialization constraints has started.");

        try {
            Set<Class<?>> beanClasses = scanner.getBeanClasses();
            if (beanClasses != null && beanClasses.size() > 0) {
                //superClassList is used to handle the case: Car, CarToyota, Bus, SchoolBus, CarFord
                //for which case, the owb should throw exception that both CarToyota and CarFord are
                //specialize Car.
                Class<?> superClass;
                ArrayList<Class<?>> superClassList = new ArrayList<Class<?>>();
                ArrayList<Class<?>> specialClassList = new ArrayList<Class<?>>();
                for (Class<?> specialClass : beanClasses) {
                    if (AnnotationUtil.hasClassAnnotation(specialClass, Specializes.class)) {
                        superClass = specialClass.getSuperclass();
                        if (superClass.equals(Object.class)) {
                            throw new WebBeansConfigurationException(logger.getTokenString(OWBLogConst.EXCEPT_0003) + specialClass.getName()
                                    + logger.getTokenString(OWBLogConst.EXCEPT_0004));
                        }
                        if (superClassList.contains(superClass)) {
                            throw new InconsistentSpecializationException(logger.getTokenString(OWBLogConst.EXCEPT_0005) + superClass.getName());
                        }
                        superClassList.add(superClass);
                        specialClassList.add(specialClass);
                    }
                }
                webBeansContext.getWebBeansUtil().configureSpecializations(specialClassList);
            }


            //configure specialized producer beans.
            webBeansContext.getWebBeansUtil().configureProducerMethodSpecializations();
        } catch (Exception e) {
            throw new WebBeansDeploymentException(e);
        }


        logger.debug("Checking Specialization constraints has ended.");
    }


    /**
     * Check passivations.
     */
    protected void checkPassivationScope(Bean<?> beanObj)
    {
        boolean validate = false;
        if (beanObj instanceof OwbBean && !((OwbBean)beanObj).isEnabled())
        {
            // we skip disabled beans
            return;
        }


        if (EnterpriseBeanMarker.class.isAssignableFrom(beanObj.getClass())) {
            EnterpriseBeanMarker marker = (EnterpriseBeanMarker) beanObj;
            if (marker.isPassivationCapable()) {
                validate = true;
            }
        } else if (webBeansContext.getBeanManagerImpl().isPassivatingScope(beanObj.getScope())) {
            if (WebBeansUtil.isPassivationCapable(beanObj) == null) {
                if (!(beanObj instanceof AbstractProducerBean)) {
                    throw new WebBeansConfigurationException("Passivation scoped defined bean must be passivation capable, " +
                            "but bean : " + beanObj.toString() + " is not passivation capable");
                } else {
                    validate = true;
                }
            }

            validate = true;
        }

        if (validate) {
            ((OwbBean<?>) beanObj).validatePassivationDependencies();
        }
    }

    /**
     * Check steretypes.
     * @param scanner scanner instance
     */
    protected void checkStereoTypes(ScannerService scanner)
    {
        logger.debug("Checking StereoType constraints has started.");

        addDefaultStereoTypes();

        final AnnotationManager annotationManager = webBeansContext.getAnnotationManager();

        Set<Class<?>> beanClasses = scanner.getBeanClasses();
        if (beanClasses != null && beanClasses.size() > 0)
        {
            for(Class<?> beanClass : beanClasses)
            {
                if(beanClass.isAnnotation())
                {
                    Class<? extends Annotation> stereoClass = (Class<? extends Annotation>) beanClass;
                    if (annotationManager.isStereoTypeAnnotation(stereoClass))
                    {
                        annotationManager.checkStereoTypeClass(stereoClass, stereoClass.getDeclaredAnnotations());
                        StereoTypeModel model = new StereoTypeModel(webBeansContext, stereoClass);
                        webBeansContext.getStereoTypeManager().addStereoTypeModel(model);
                    }
                }
            }
        }

        logger.debug("Checking StereoType constraints has ended.");
    }

    /**
     * Adds default stereotypes.
     */
    protected void addDefaultStereoTypes()
    {
        StereoTypeModel model = new StereoTypeModel(webBeansContext, Model.class);
        webBeansContext.getStereoTypeManager().addStereoTypeModel(model);

        model = new StereoTypeModel(webBeansContext, javax.decorator.Decorator.class);
        webBeansContext.getStereoTypeManager().addStereoTypeModel(model);

        model = new StereoTypeModel(webBeansContext, Interceptor.class);
        webBeansContext.getStereoTypeManager().addStereoTypeModel(model);
    }

    /**
     * Defines and configures managed bean.
     * @param <T> type info
     * @param clazz bean class
     * @return true if given class is configured as a managed bean
     */
    protected <T> boolean defineManagedBean(Class<T> clazz, ProcessAnnotatedTypeImpl<T> processAnnotatedEvent)
    {
        //Bean manager
        BeanManagerImpl manager = webBeansContext.getBeanManagerImpl();

        //Create an annotated type
        AnnotatedType<T> annotatedType = processAnnotatedEvent.getAnnotatedType();

        //Fires ProcessInjectionTarget event for Java EE components instances
        //That supports injections but not managed beans
        ProcessInjectionTargetImpl<T> processInjectionTargetEvent = null;
        if (webBeansContext.getWebBeansUtil().supportsJavaEeComponentInjections(clazz)) {
            //Fires ProcessInjectionTarget
            processInjectionTargetEvent = webBeansContext.getWebBeansUtil().fireProcessInjectionTargetEventForJavaEeComponents(clazz);
            webBeansContext.getWebBeansUtil().inspectErrorStack("There are errors that are added by ProcessInjectionTarget event observers. Look at logs for further details");

            //Sets custom InjectionTarget instance
            if (processInjectionTargetEvent.isSet()) {
                //Adding injection target
                manager.putInjectionTargetWrapperForJavaEeComponents(clazz, new InjectionTargetWrapper<T>(processInjectionTargetEvent.getInjectionTarget()));
            }

            //Checks that not contains @Inject InjectionPoint
            webBeansContext.getAnnotationManager().checkInjectionPointForInjectInjectionPoint(clazz);
        }

        //Check for whether this class is candidate for Managed Bean
        if (webBeansContext.getManagedBeanConfigurator().isManagedBean(clazz)) {
            //Check conditions
            webBeansContext.getManagedBeanConfigurator().checkManagedBeanCondition(clazz);

            //Temporary managed bean instance creationa
            ManagedBean<T> managedBean = new ManagedBean<T>(clazz, WebBeansType.MANAGED, webBeansContext);
            ManagedBeanCreatorImpl<T> managedBeanCreator = new ManagedBeanCreatorImpl<T>(managedBean);

            boolean annotationTypeSet = false;
            if (processAnnotatedEvent.isModifiedAnnotatedType()) {
                annotationTypeSet = true;
                managedBean.setAnnotatedType(annotatedType);
                annotatedType = processAnnotatedEvent.getAnnotatedType();
                managedBeanCreator.setAnnotatedType(annotatedType);
                managedBeanCreator.setMetaDataProvider(MetaDataProvider.THIRDPARTY);
            }

            //If ProcessInjectionTargetEvent is not set, set it
            if (processInjectionTargetEvent == null) {
                processInjectionTargetEvent = webBeansContext.getWebBeansUtil().fireProcessInjectionTargetEvent(managedBean);
            }

            //Decorator
            if (WebBeansUtil.isAnnotatedTypeDecorator(annotatedType)) {
                if (logger.wblWillLogDebug()) {
                    logger.debug("Found Managed Bean Decorator with class name : [{0}]", annotatedType.getJavaClass().getName());
                }
                if (annotationTypeSet) {
                    webBeansContext.getWebBeansUtil().defineDecorator(annotatedType);
                } else {
                    webBeansContext.getWebBeansUtil().defineDecorator(managedBeanCreator, processInjectionTargetEvent);
                }
            }
            //Interceptor
            else if (WebBeansUtil.isAnnotatedTypeInterceptor(annotatedType)) {
                if (logger.wblWillLogDebug()) {
                    logger.debug("Found Managed Bean Interceptor with class name : [{0}]", annotatedType.getJavaClass().getName());
                }
                if (annotationTypeSet) {
                    webBeansContext.getWebBeansUtil().defineInterceptor(annotatedType);
                } else {
                    webBeansContext.getWebBeansUtil().defineInterceptor(managedBeanCreator, processInjectionTargetEvent);
                }
            } else {
                if (webBeansContext.getBeanManagerImpl().containsCustomDecoratorClass(annotatedType.getJavaClass()) ||
                        webBeansContext.getBeanManagerImpl().containsCustomInterceptorClass(annotatedType.getJavaClass())) {
                    return false;
                }

                if (logger.wblWillLogDebug()) {
                    logger.debug("Found Managed Bean with class name : [{0}]", annotatedType.getJavaClass().getName());
                }
                webBeansContext.getWebBeansUtil().defineManagedBean(managedBeanCreator, processInjectionTargetEvent, false);
            }

            return true;
        }
        //Not a managed bean
        else {
            return false;
        }
    }
}
TOP

Related Classes of org.apache.openejb.cdi.BeansDeployer

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.