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

org.jboss.weld.bootstrap.AbstractBeanDeployer Maven / Gradle / Ivy

There is a newer version: 3.0.0.Alpha1
Show newest version
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2008, Red Hat, Inc., and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * Licensed 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.jboss.weld.bootstrap;

import java.lang.reflect.Member;
import java.util.Set;

import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.BeanAttributes;
import javax.enterprise.inject.spi.ProcessProducerField;
import javax.enterprise.inject.spi.ProcessProducerMethod;

import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedField;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedMethod;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedType;
import org.jboss.weld.annotated.slim.SlimAnnotatedTypeStore;
import org.jboss.weld.bean.AbstractBean;
import org.jboss.weld.bean.AbstractClassBean;
import org.jboss.weld.bean.AbstractProducerBean;
import org.jboss.weld.bean.DecoratorImpl;
import org.jboss.weld.bean.DisposalMethod;
import org.jboss.weld.bean.InterceptorImpl;
import org.jboss.weld.bean.ManagedBean;
import org.jboss.weld.bean.NewBean;
import org.jboss.weld.bean.NewManagedBean;
import org.jboss.weld.bean.NewSessionBean;
import org.jboss.weld.bean.ProducerField;
import org.jboss.weld.bean.ProducerMethod;
import org.jboss.weld.bean.RIBean;
import org.jboss.weld.bean.SessionBean;
import org.jboss.weld.bean.attributes.BeanAttributesFactory;
import org.jboss.weld.bean.attributes.ExternalBeanAttributesFactory;
import org.jboss.weld.bean.builtin.AbstractBuiltInBean;
import org.jboss.weld.bean.builtin.ExtensionBean;
import org.jboss.weld.bean.builtin.ee.EEResourceProducerField;
import org.jboss.weld.bean.builtin.ee.StaticEEResourceProducerField;
import org.jboss.weld.bootstrap.api.ServiceRegistry;
import org.jboss.weld.bootstrap.events.ContainerLifecycleEvents;
import org.jboss.weld.bootstrap.events.ProcessBeanAttributesImpl;
import org.jboss.weld.bootstrap.events.ProcessObserverMethodImpl;
import org.jboss.weld.ejb.EJBApiAbstraction;
import org.jboss.weld.ejb.InternalEjbDescriptor;
import org.jboss.weld.event.ObserverFactory;
import org.jboss.weld.event.ObserverMethodImpl;
import org.jboss.weld.logging.BeanLogger;
import org.jboss.weld.logging.BootstrapLogger;
import org.jboss.weld.manager.BeanManagerImpl;
import org.jboss.weld.persistence.PersistenceApiAbstraction;
import org.jboss.weld.resources.ClassTransformer;
import org.jboss.weld.util.BeanMethods;
import org.jboss.weld.util.Observers;
import org.jboss.weld.util.collections.WeldCollections;
import org.jboss.weld.util.reflection.Reflections;
import org.jboss.weld.ws.WSApiAbstraction;

/**
 * @author Pete Muir
 * @author Ales Justin
 * @author Jozef Hartinger
 */
public class AbstractBeanDeployer {

    private final BeanManagerImpl manager;
    private final ServiceRegistry services;
    private final E environment;
    protected final ContainerLifecycleEvents containerLifecycleEvents;
    protected final ClassTransformer classTransformer;
    protected final SlimAnnotatedTypeStore slimAnnotatedTypeStore;
    protected final SpecializationAndEnablementRegistry specializationAndEnablementRegistry;

    public AbstractBeanDeployer(BeanManagerImpl manager, ServiceRegistry services, E environment) {
        this.manager = manager;
        this.services = services;
        this.environment = environment;
        this.containerLifecycleEvents = manager.getServices().get(ContainerLifecycleEvents.class);
        this.classTransformer = services.get(ClassTransformer.class);
        this.slimAnnotatedTypeStore = services.get(SlimAnnotatedTypeStore.class);
        this.specializationAndEnablementRegistry = services.get(SpecializationAndEnablementRegistry.class);
    }

    protected BeanManagerImpl getManager() {
        return manager;
    }

    // interceptors, decorators and observers go first
    public AbstractBeanDeployer deploySpecialized() {
        // ensure that all decorators are initialized before initializing
        // the rest of the beans
        for (DecoratorImpl bean : getEnvironment().getDecorators()) {
            bean.initialize(getEnvironment());
            containerLifecycleEvents.fireProcessBean(getManager(), bean);
            manager.addDecorator(bean);
            BootstrapLogger.LOG.foundDecorator(bean);
        }
        for (InterceptorImpl bean : getEnvironment().getInterceptors()) {
            bean.initialize(getEnvironment());
            containerLifecycleEvents.fireProcessBean(getManager(), bean);
            manager.addInterceptor(bean);
            BootstrapLogger.LOG.foundInterceptor(bean);
        }
        return this;
    }

    public AbstractBeanDeployer initializeBeans() {
        for (RIBean bean : getEnvironment().getBeans()) {
            bean.initialize(getEnvironment());
        }
        return this;
    }

    public AbstractBeanDeployer fireBeanEvents() {
        for (RIBean bean : getEnvironment().getBeans()) {
            fireBeanEvents(bean);
        }
        return this;
    }

    public void fireBeanEvents(RIBean bean) {
        if (!(bean instanceof NewBean)) {
            if (bean instanceof AbstractProducerBean) {
                containerLifecycleEvents.fireProcessProducer(manager, Reflections.>cast(bean));
            } else if (bean instanceof AbstractClassBean) {
                containerLifecycleEvents.fireProcessInjectionTarget(manager, (AbstractClassBean) bean);
            }
            containerLifecycleEvents.fireProcessBean(getManager(), bean);
        }
    }

    public AbstractBeanDeployer deployBeans() {
        manager.addBeans(getEnvironment().getBeans());
        return this;
    }

    public AbstractBeanDeployer initializeObserverMethods() {
        for (ObserverInitializationContext observerInitializer : getEnvironment().getObservers()) {
            if (Observers.isObserverMethodEnabled(observerInitializer.getObserver(), manager)) {
                observerInitializer.initialize();
            }
        }
        return this;
    }

    public AbstractBeanDeployer deployObserverMethods() {
        // TODO -- why do observers have to be the last?
        for (ObserverInitializationContext observerInitializer : getEnvironment().getObservers()) {
            if (Observers.isObserverMethodEnabled(observerInitializer.getObserver(), manager)) {
                BootstrapLogger.LOG.foundObserverMethod(observerInitializer.getObserver());
                ProcessObserverMethodImpl.fire(manager, observerInitializer.getObserver());
                manager.addObserver(observerInitializer.getObserver());
            }
        }
        return this;
    }

    /**
     * Creates the sub bean for an class (simple or enterprise) bean
     *
     * @param bean The class bean
     */
    protected  void createObserversProducersDisposers(AbstractClassBean bean) {
        if (bean instanceof ManagedBean || bean instanceof SessionBean) {
            // disposal methods have to go first as we want them to be ready for resolution when initializing producer method/fields
            createDisposalMethods(bean, bean.getEnhancedAnnotated());
            createProducerMethods(bean, bean.getEnhancedAnnotated());
            createProducerFields(bean, bean.getEnhancedAnnotated());
            if (manager.isBeanEnabled(bean)) {
                createObserverMethods(bean, bean.getEnhancedAnnotated());
            }
        }
    }

    protected  DisposalMethod resolveDisposalMethod(BeanAttributes attributes, AbstractClassBean declaringBean) {
        Set> disposalBeans = environment.resolveDisposalBeans(attributes.getTypes(), attributes.getQualifiers(), declaringBean);

        if (disposalBeans.size() == 1) {
            return disposalBeans.iterator().next();
        } else if (disposalBeans.size() > 1) {
            throw BeanLogger.LOG.multipleDisposalMethods(this, WeldCollections.toMultiRowString(disposalBeans));
        }
        return null;
    }

    protected  void createProducerMethods(AbstractClassBean declaringBean, EnhancedAnnotatedType type) {
        for (EnhancedAnnotatedMethod method : BeanMethods.filterOutBridgeMethods(type.getDeclaredEnhancedMethods(Produces.class))) {
            // create method for now
            // specialization and PBA processing is handled later
            createProducerMethod(declaringBean, method);
        }
    }

    protected  void createDisposalMethods(AbstractClassBean declaringBean, EnhancedAnnotatedType annotatedClass) {
        for (EnhancedAnnotatedMethod method : BeanMethods.filterOutBridgeMethods(annotatedClass
                .getDeclaredEnhancedMethodsWithAnnotatedParameters(Disposes.class))) {
            DisposalMethod disposalBean = DisposalMethod.of(manager, method, declaringBean);
            getEnvironment().addDisposesMethod(disposalBean);
        }
    }

    protected  void createProducerMethod(AbstractClassBean declaringBean, EnhancedAnnotatedMethod annotatedMethod) {
        BeanAttributes attributes = BeanAttributesFactory.forBean(annotatedMethod, getManager());
        DisposalMethod disposalMethod = resolveDisposalMethod(attributes, declaringBean);
        ProducerMethod bean = ProducerMethod.of(attributes, annotatedMethod, declaringBean, disposalMethod, manager, services);
        containerLifecycleEvents.preloadProcessBeanAttributes(bean.getType());
        containerLifecycleEvents.preloadProcessBean(ProcessProducerMethod.class, annotatedMethod.getBaseType(), bean.getBeanClass());
        containerLifecycleEvents.preloadProcessProducer(bean.getBeanClass(), annotatedMethod.getBaseType());
        getEnvironment().addProducerMethod(bean);
    }

    protected  void createProducerField(AbstractClassBean declaringBean, EnhancedAnnotatedField field) {
        BeanAttributes attributes = BeanAttributesFactory.forBean(field, getManager());
        DisposalMethod disposalMethod = resolveDisposalMethod(attributes, declaringBean);
        ProducerField bean;
        if (isEEResourceProducerField(field)) {
            if (field.isStatic()) {
                bean = StaticEEResourceProducerField.of(attributes, field, declaringBean, disposalMethod, manager, services);
            } else {
                bean = EEResourceProducerField.of(attributes, field, declaringBean, disposalMethod, manager, services);
            }
        } else {
            bean = ProducerField.of(attributes, field, declaringBean, disposalMethod, manager, services);
        }
        containerLifecycleEvents.preloadProcessBeanAttributes(bean.getType());
        containerLifecycleEvents.preloadProcessBean(ProcessProducerField.class, field.getBaseType(), bean.getBeanClass());
        containerLifecycleEvents.preloadProcessProducer(bean.getBeanClass(), field.getBaseType());
        getEnvironment().addProducerField(bean);
    }

    protected  void createProducerFields(AbstractClassBean declaringBean, EnhancedAnnotatedType annotatedClass) {
        for (EnhancedAnnotatedField field : annotatedClass.getDeclaredEnhancedFields(Produces.class)) {
            createProducerField(declaringBean, field);
        }
    }

    protected  void createObserverMethods(AbstractClassBean declaringBean, EnhancedAnnotatedType annotatedClass) {
        for (EnhancedAnnotatedMethod method : BeanMethods.getObserverMethods(annotatedClass)) {
            createObserverMethod(declaringBean, method);
        }
    }

    protected  void createObserverMethod(AbstractClassBean declaringBean, EnhancedAnnotatedMethod method) {
        ObserverMethodImpl observer = ObserverFactory.create(method, declaringBean, manager);
        ObserverInitializationContext observerInitializer = ObserverInitializationContext.of(observer, method);
        containerLifecycleEvents.preloadProcessObserverMethod(observer.getObservedType(), declaringBean.getBeanClass());
        getEnvironment().addObserverMethod(observerInitializer);
    }

    protected  ManagedBean createManagedBean(EnhancedAnnotatedType weldClass) {
        BeanAttributes attributes = BeanAttributesFactory.forBean(weldClass, getManager());
        ManagedBean bean = ManagedBean.of(attributes, weldClass, manager);
        getEnvironment().addManagedBean(bean);
        return bean;
    }

    protected  void createNewManagedBean(EnhancedAnnotatedType annotatedClass) {
        // TODO resolve existing beans first
        slimAnnotatedTypeStore.put(annotatedClass.slim());
        getEnvironment().addManagedBean(NewManagedBean.of(BeanAttributesFactory.forNewManagedBean(annotatedClass, manager), annotatedClass, manager));
    }

    protected  void createDecorator(EnhancedAnnotatedType weldClass) {
        BeanAttributes attributes = BeanAttributesFactory.forBean(weldClass, getManager());
        DecoratorImpl bean = DecoratorImpl.of(attributes, weldClass, manager);
        getEnvironment().addDecorator(bean);
    }

    protected  void createInterceptor(EnhancedAnnotatedType weldClass) {
        BeanAttributes attributes = BeanAttributesFactory.forBean(weldClass, getManager());
        InterceptorImpl bean = InterceptorImpl.of(attributes, weldClass, manager);
        getEnvironment().addInterceptor(bean);
    }

    protected  SessionBean createSessionBean(InternalEjbDescriptor descriptor) {
        EnhancedAnnotatedType type = classTransformer.getEnhancedAnnotatedType(descriptor.getBeanClass(), getManager().getId());
        slimAnnotatedTypeStore.put(type.slim());
        return createSessionBean(descriptor, type);
    }
    protected  SessionBean createSessionBean(InternalEjbDescriptor descriptor, EnhancedAnnotatedType weldClass) {
        // TODO Don't create enterprise bean if it has no local interfaces!
        BeanAttributes attributes = BeanAttributesFactory.forSessionBean(weldClass, descriptor, getManager());
        SessionBean bean = SessionBean.of(attributes, descriptor, manager, weldClass);
        getEnvironment().addSessionBean(bean);
        return bean;
    }

    protected  void createNewSessionBean(InternalEjbDescriptor ejbDescriptor, BeanAttributes originalAttributes, EnhancedAnnotatedType type) {
        slimAnnotatedTypeStore.put(type.slim());
        BeanAttributes attributes = Reflections.cast(BeanAttributesFactory.forNewSessionBean(originalAttributes, type.getJavaClass()));
        getEnvironment().addSessionBean(NewSessionBean.of(attributes, ejbDescriptor, manager));
    }

    protected boolean isEEResourceProducerField(EnhancedAnnotatedField field) {
        EJBApiAbstraction ejbApiAbstraction = manager.getServices().get(EJBApiAbstraction.class);
        PersistenceApiAbstraction persistenceApiAbstraction = manager.getServices().get(PersistenceApiAbstraction.class);
        WSApiAbstraction wsApiAbstraction = manager.getServices().get(WSApiAbstraction.class);
        return field.isAnnotationPresent(ejbApiAbstraction.EJB_ANNOTATION_CLASS) || field.isAnnotationPresent(ejbApiAbstraction.RESOURCE_ANNOTATION_CLASS) || field.isAnnotationPresent(persistenceApiAbstraction.PERSISTENCE_UNIT_ANNOTATION_CLASS) || field.isAnnotationPresent(persistenceApiAbstraction.PERSISTENCE_CONTEXT_ANNOTATION_CLASS) || field.isAnnotationPresent(wsApiAbstraction.WEB_SERVICE_REF_ANNOTATION_CLASS);
    }

    public E getEnvironment() {
        return environment;
    }

    public void addBuiltInBean(AbstractBuiltInBean bean) {
        getEnvironment().addBuiltInBean(bean);
    }

    public void addExtension(ExtensionBean bean) {
        getEnvironment().addExtension(bean);
    }

    protected  boolean fireProcessBeanAttributes(AbstractBean bean) {
        if (!specializationAndEnablementRegistry.isCandidateForLifecycleEvent(bean)) {
            return false;
        }

        ProcessBeanAttributesImpl event = containerLifecycleEvents.fireProcessBeanAttributes(getManager(), bean, bean.getAnnotated(), bean.getType());
        if (event == null) {
            return false;
        }
        if (event.isVeto()) {
            return true;
        }
        if (event.isDirty()) {
            bean.setAttributes(ExternalBeanAttributesFactory.of(event.getBeanAttributes(), manager));
            bean.checkSpecialization();
        }
        return false;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy