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

org.jboss.weld.bootstrap.events.ContainerLifecycleEvents Maven / Gradle / Ivy

There is a newer version: 3.0.0.Alpha1
Show newest version
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2012, 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.events;

import java.lang.annotation.Annotation;
import java.lang.reflect.Member;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanAttributes;
import javax.enterprise.inject.spi.InjectionTarget;
import javax.enterprise.inject.spi.ObserverMethod;
import javax.enterprise.inject.spi.ProcessAnnotatedType;
import javax.enterprise.inject.spi.ProcessBean;
import javax.enterprise.inject.spi.ProcessBeanAttributes;
import javax.enterprise.inject.spi.ProcessInjectionPoint;
import javax.enterprise.inject.spi.ProcessInjectionTarget;
import javax.enterprise.inject.spi.ProcessObserverMethod;
import javax.enterprise.inject.spi.ProcessProducer;
import javax.enterprise.inject.spi.ProcessSyntheticAnnotatedType;

import org.jboss.weld.annotated.slim.SlimAnnotatedType;
import org.jboss.weld.annotated.slim.SlimAnnotatedTypeContext;
import org.jboss.weld.bean.AbstractClassBean;
import org.jboss.weld.bean.AbstractProducerBean;
import org.jboss.weld.bean.ManagedBean;
import org.jboss.weld.bean.ProducerField;
import org.jboss.weld.bean.ProducerMethod;
import org.jboss.weld.bean.SessionBean;
import org.jboss.weld.bootstrap.api.helpers.AbstractBootstrapService;
import org.jboss.weld.event.ExtensionObserverMethodImpl;
import org.jboss.weld.exceptions.DefinitionException;
import org.jboss.weld.injection.attributes.FieldInjectionPointAttributes;
import org.jboss.weld.injection.attributes.ParameterInjectionPointAttributes;
import org.jboss.weld.logging.BootstrapLogger;
import org.jboss.weld.manager.BeanManagerImpl;
import org.jboss.weld.resolution.Resolvable;
import org.jboss.weld.util.reflection.Reflections;

public class ContainerLifecycleEvents extends AbstractBootstrapService {

    private boolean everythingObserved;
    private boolean processAnnotatedTypeObserved;
    private boolean processBeanObserved;
    private boolean processBeanAttributesObserved;
    private boolean processInjectionPointObserved;
    private boolean processInjectionTargetObserved;
    private boolean processProducerObserved;
    private boolean processObserverMethodObserved;
    private final RequiredAnnotationDiscovery discovery;

    private final ContainerLifecycleEventPreloader preloader;

    public ContainerLifecycleEvents(ContainerLifecycleEventPreloader preloader, RequiredAnnotationDiscovery discovery) {
        this.preloader = preloader;
        this.discovery = discovery;
    }

    public void processObserverMethod(ObserverMethod observer) {
        if (observer instanceof ExtensionObserverMethodImpl) {
            processObserverMethodType(observer.getObservedType());
        }
    }

    protected void processObserverMethodType(Type observedType) {
        if (everythingObserved) {
            return;
        }

        Class rawType = Reflections.getRawType(observedType);
        if (Object.class.equals(rawType)) {
            this.everythingObserved = true;
            this.processAnnotatedTypeObserved = true;
            this.processBeanObserved = true;
            this.processBeanAttributesObserved = true;
            this.processInjectionPointObserved = true;
            this.processInjectionTargetObserved = true;
            this.processProducerObserved = true;
            this.processObserverMethodObserved = true;
        } else if (!processAnnotatedTypeObserved && ProcessAnnotatedType.class.isAssignableFrom(rawType)) {
            processAnnotatedTypeObserved = true;
        } else if (!processBeanObserved && ProcessBean.class.isAssignableFrom(rawType)) {
            processBeanObserved = true;
        } else if (!processBeanAttributesObserved && ProcessBeanAttributes.class.isAssignableFrom(rawType)) {
            processBeanAttributesObserved = true;
        } else if (!processObserverMethodObserved && ProcessObserverMethod.class.isAssignableFrom(rawType)) {
            processObserverMethodObserved = true;
        } else if (!processProducerObserved && ProcessProducer.class.equals(rawType)) {
            processProducerObserved = true;
        } else if (!processInjectionTargetObserved && ProcessInjectionTarget.class.equals(rawType)) {
            processInjectionTargetObserved = true;
        } else if (!processInjectionPointObserved && ProcessInjectionPoint.class.equals(rawType)) {
            processInjectionPointObserved = true;
        }
    }

    public boolean isProcessAnnotatedTypeObserved() {
        return processAnnotatedTypeObserved;
    }

    public boolean isProcessBeanObserved() {
        return processBeanObserved;
    }

    public boolean isProcessBeanAttributesObserved() {
        return processBeanAttributesObserved;
    }

    public boolean isProcessObserverMethodObserved() {
        return processObserverMethodObserved;
    }

    public boolean isProcessProducerObserved() {
        return processProducerObserved;
    }

    public boolean isProcessInjectionTargetObserved() {
        return processInjectionTargetObserved;
    }

    public boolean isProcessInjectionPointObserved() {
        return processInjectionPointObserved;
    }

    public  ProcessAnnotatedTypeImpl fireProcessAnnotatedType(BeanManagerImpl beanManager, SlimAnnotatedTypeContext annotatedTypeContext) {
        if (!isProcessAnnotatedTypeObserved()) {
            return null;
        }
        final Set> observers = annotatedTypeContext.getResolvedProcessAnnotatedTypeObservers();
        final SlimAnnotatedType annotatedType = annotatedTypeContext.getAnnotatedType();
        // if the fast resolver resolved an empty set of observer methods, skip this event
        if (observers != null && observers.isEmpty()) {
            BootstrapLogger.LOG.patSkipped(annotatedType);
            return null;
        }

        ProcessAnnotatedTypeImpl event = null;
        if (annotatedTypeContext.getExtension() == null) {
            event = new ProcessAnnotatedTypeImpl(beanManager, annotatedType);
        } else {
            event = new ProcessSyntheticAnnotatedTypeImpl(beanManager, annotatedTypeContext);
        }

        if (observers == null) {
            BootstrapLogger.LOG.patDefaultResolver(annotatedType);
            fireProcessAnnotatedType(event, beanManager);
        } else {
            BootstrapLogger.LOG.patFastResolver(annotatedType);
            fireProcessAnnotatedType(event, annotatedTypeContext.getResolvedProcessAnnotatedTypeObservers());
        }
        return event;
    }

    /**
     * Fires a {@link ProcessAnnotatedType} or {@link ProcessSyntheticAnnotatedType} using the default event mechanism.
     */
    private void fireProcessAnnotatedType(ProcessAnnotatedTypeImpl event, BeanManagerImpl beanManager) {
        final Resolvable resolvable = ProcessAnnotatedTypeEventResolvable.of(event, discovery);
        try {
            beanManager.getGlobalLenientObserverNotifier().fireEvent(event, resolvable);
        } catch (Exception e) {
            throw new DefinitionException(e);
        }
    }

    /**
     * Fires a {@link ProcessAnnotatedType}. Instead of using the default event dispatching mechanism, this method directly notifies
     * extension observers resolved by FastProcessAnnotatedTypeResolver.
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    private void fireProcessAnnotatedType(ProcessAnnotatedTypeImpl event, Set> observers) {
        List errors = new LinkedList();
        for (ExtensionObserverMethodImpl observer : observers) {
            // FastProcessAnnotatedTypeResolver does not consider special scope inheritance rules (see CDI - section 4.1)
            if (checkScopeInheritanceRules(event.getOriginalAnnotatedType(), observer)) {
                try {
                    observer.notify(event);
                } catch (Throwable e) {
                    errors.add(e);
                }
            }
        }
        if (!errors.isEmpty()) {
            throw new DefinitionException(errors);
        }
    }

    private boolean checkScopeInheritanceRules(SlimAnnotatedType type, ExtensionObserverMethodImpl observer) {
        Collection> scopes = observer.getRequiredScopeAnnotations();
        if (!scopes.isEmpty() && scopes.size() == observer.getRequiredScopeAnnotations().size()) {
            // this check only works if only scope annotations are listed within @WithAnnotations
            // performing a complete check would be way too expensive - eliminating the benefit of ClassFileServices
            for (Class annotation : scopes) {
                if (type.isAnnotationPresent(annotation)) {
                    return true;
                }
            }
            return false;
        }
        return true;
    }


    public void fireProcessBean(BeanManagerImpl beanManager, Bean bean) {
        if (isProcessBeanObserved()) {
            if (bean instanceof ManagedBean) {
                ProcessManagedBeanImpl.fire(beanManager, (ManagedBean) bean);
            } else if (bean instanceof SessionBean) {
                ProcessSessionBeanImpl.fire(beanManager, Reflections.> cast(bean));
            } else if (bean instanceof ProducerField) {
                ProcessProducerFieldImpl.fire(beanManager, (ProducerField) bean);
            } else if (bean instanceof ProducerMethod) {
                ProcessProducerMethodImpl.fire(beanManager, (ProducerMethod) bean);
            } else {
                ProcessBeanImpl.fire(beanManager, bean);
            }
        }
    }

    public  ProcessBeanAttributesImpl fireProcessBeanAttributes(BeanManagerImpl beanManager, BeanAttributes attributes, Annotated annotated, Type type) {
        if (isProcessBeanAttributesObserved()) {
            return ProcessBeanAttributesImpl.fire(beanManager, attributes, annotated, type);
        }
        return null;
    }

    public void fireProcessInjectionTarget(BeanManagerImpl beanManager, AbstractClassBean bean) {
        if (isProcessInjectionTargetObserved()) {
            AbstractProcessInjectionTarget.fire(beanManager, bean);
        }
    }

    public  InjectionTarget fireProcessInjectionTarget(BeanManagerImpl beanManager, AnnotatedType annotatedType, InjectionTarget injectionTarget) {
        if (isProcessInjectionTargetObserved()) {
            return AbstractProcessInjectionTarget.fire(beanManager, annotatedType, injectionTarget);
        }
        return injectionTarget;
    }

    public  FieldInjectionPointAttributes fireProcessInjectionPoint(FieldInjectionPointAttributes attributes, Class declaringComponentClass,
            BeanManagerImpl manager) {
        if (isProcessInjectionPointObserved()) {
            return ProcessInjectionPointImpl.fire(attributes, declaringComponentClass, manager);
        }
        return attributes;
    }

    public  ParameterInjectionPointAttributes fireProcessInjectionPoint(ParameterInjectionPointAttributes injectionPointAttributes,
            Class declaringComponentClass, BeanManagerImpl manager) {
        if (isProcessInjectionPointObserved()) {
            return ProcessInjectionPointImpl.fire(injectionPointAttributes, declaringComponentClass, manager);
        }
        return injectionPointAttributes;
    }

    public void fireProcessObserverMethod(BeanManagerImpl beanManager, ObserverMethod observer) {
        if (isProcessObserverMethodObserved()) {
            ProcessObserverMethodImpl.fire(beanManager, observer);
        }
    }

    public void fireProcessProducer(BeanManagerImpl beanManager, AbstractProducerBean bean) {
        if (isProcessProducerObserved()) {
            ProcessProducerImpl.fire(beanManager, bean);
        }
    }

    public void preloadProcessAnnotatedType(Class type) {
        if (preloader != null && isProcessAnnotatedTypeObserved()) {
            preloader.preloadContainerLifecycleEvent(ProcessAnnotatedType.class, type);
        }
    }

    public > void preloadProcessBean(Class eventRawType, Type... typeParameters) {
        if (preloader != null && isProcessBeanObserved()) {
            preloader.preloadContainerLifecycleEvent(ProcessAnnotatedType.class, typeParameters);
        }
    }

    public void preloadProcessBeanAttributes(Type type) {
        if (preloader != null && isProcessBeanAttributesObserved()) {
            preloader.preloadContainerLifecycleEvent(ProcessBeanAttributes.class, type);
        }
    }

    public void preloadProcessInjectionPoint(Type... typeParameters) {
        if (preloader != null && isProcessInjectionPointObserved()) {
            preloader.preloadContainerLifecycleEvent(ProcessInjectionPoint.class, typeParameters);
        }
    }

    public void preloadProcessInjectionTarget(Class type) {
        if (preloader != null && isProcessInjectionTargetObserved()) {
            preloader.preloadContainerLifecycleEvent(ProcessInjectionTarget.class, type);
        }
    }

    public void preloadProcessObserverMethod(Type... typeParameters) {
        if (preloader != null && isProcessObserverMethodObserved()) {
            preloader.preloadContainerLifecycleEvent(ProcessObserverMethod.class, typeParameters);
        }
    }

    public void preloadProcessProducer(Type... typeParameters) {
        if (preloader != null && isProcessProducerObserved()) {
            preloader.preloadContainerLifecycleEvent(ProcessProducer.class, typeParameters);
        }
    }

    @Override
    public void cleanupAfterBoot() {
        if (preloader != null) {
            preloader.shutdown();
        }
    }

    public boolean isPreloaderEnabled() {
        return preloader != null;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy