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

org.jboss.weld.bootstrap.BeanDeployerEnvironment 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.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.enterprise.event.Event;
import javax.enterprise.inject.Instance;
import javax.enterprise.inject.New;

import org.jboss.weld.bean.AbstractBean;
import org.jboss.weld.bean.AbstractClassBean;
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.builtin.AbstractBuiltInBean;
import org.jboss.weld.bean.builtin.ExtensionBean;
import org.jboss.weld.ejb.EjbDescriptors;
import org.jboss.weld.ejb.InternalEjbDescriptor;
import org.jboss.weld.event.ObserverMethodImpl;
import org.jboss.weld.injection.WeldInjectionPoint;
import org.jboss.weld.introspector.WeldClass;
import org.jboss.weld.introspector.WeldMethod;
import org.jboss.weld.manager.BeanManagerImpl;
import org.jboss.weld.resolution.ResolvableBuilder;
import org.jboss.weld.resolution.TypeSafeDisposerResolver;
import org.jboss.weld.resources.ClassTransformer;
import org.jboss.weld.util.AnnotatedTypes;
import org.jboss.weld.util.reflection.Reflections;

import static org.jboss.weld.util.reflection.Reflections.cast;

public class BeanDeployerEnvironment {

    private final Map, AbstractClassBean> classBeanMap;
    private final Map, ProducerMethod> producerMethodBeanMap;
    private final Set> beans;
    private final Set> observers;
    private final List> allDisposalBeans;
    private final Set> resolvedDisposalBeans;
    private final Set> decorators;
    private final Set> interceptors;
    private final EjbDescriptors ejbDescriptors;
    private final TypeSafeDisposerResolver disposalMethodResolver;
    private final ClassTransformer classTransformer;
    private final Set> newManagedBeanClasses;
    private final Set> newSessionBeanDescriptors;
    private final BeanManagerImpl beanManager;

    public BeanDeployerEnvironment(EjbDescriptors ejbDescriptors, BeanManagerImpl manager) {
        this.classBeanMap = new HashMap, AbstractClassBean>();
        this.producerMethodBeanMap = new HashMap, ProducerMethod>();
        this.allDisposalBeans = new ArrayList>();
        this.resolvedDisposalBeans = new HashSet>();
        this.beans = new HashSet>();
        this.decorators = new HashSet>();
        this.interceptors = new HashSet>();
        this.observers = new HashSet>();
        this.ejbDescriptors = ejbDescriptors;
        this.disposalMethodResolver = new TypeSafeDisposerResolver(manager, allDisposalBeans);
        this.classTransformer = manager.getServices().get(ClassTransformer.class);
        this.newManagedBeanClasses = new HashSet>();
        this.newSessionBeanDescriptors = new HashSet>();
        this.beanManager = manager;
    }

    public Set> getNewManagedBeanClasses() {
        return newManagedBeanClasses;
    }

    public Set> getNewSessionBeanDescriptors() {
        return newSessionBeanDescriptors;
    }

    public  ProducerMethod getProducerMethod(WeldMethod method) {
        WeldMethodKey key = new WeldMethodKey(method);
        ProducerMethod bean = producerMethodBeanMap.get(key);
        if (bean != null) {
            bean.initialize(this);
        }
        return cast(bean);
    }

    public AbstractClassBean getClassBean(WeldClass clazz) {
        AbstractClassBean bean = classBeanMap.get(clazz);
        if (bean != null) {
            bean.initialize(this);
        }
        return bean;
    }

    public void addProducerMethod(ProducerMethod bean) {
        producerMethodBeanMap.put(WeldMethodKey.of(bean.getWeldAnnotated()), bean);
        addAbstractBean(bean);
    }

    public void addProducerField(ProducerField bean) {
        addAbstractBean(bean);
    }

    public void addExtension(ExtensionBean bean) {
        beans.add(bean);
    }

    public void addBuiltInBean(AbstractBuiltInBean bean) {
        beans.add(bean);
    }

    protected void addAbstractClassBean(AbstractClassBean bean) {
        if (!(bean instanceof NewBean)) {
            classBeanMap.put(bean.getWeldAnnotated(), bean);
        }
        addAbstractBean(bean);
    }

    public void addManagedBean(ManagedBean bean) {
        addAbstractClassBean(bean);
    }

    public void addSessionBean(SessionBean bean) {
        addAbstractClassBean(bean);
    }

    public void addNewManagedBean(NewManagedBean bean) {
        beans.add(bean);
    }

    public void addNewSessionBean(NewSessionBean bean) {
        beans.add(bean);
    }

    protected void addAbstractBean(AbstractBean bean) {
        addNewBeansFromInjectionPoints(bean);
        beans.add(bean);
    }

    public void addDecorator(DecoratorImpl bean) {
        decorators.add(bean);
    }

    public void addInterceptor(InterceptorImpl bean) {
        interceptors.add(bean);
    }

    public void addDisposesMethod(DisposalMethod bean) {
        allDisposalBeans.add(bean);
        addNewBeansFromInjectionPoints(bean);
    }

    public void addObserverMethod(ObserverMethodImpl observer) {
        this.observers.add(observer);
        addNewBeansFromInjectionPoints(observer.getNewInjectionPoints());
    }

    private void addNewBeansFromInjectionPoints(AbstractBean bean) {
        addNewBeansFromInjectionPoints(bean.getNewInjectionPoints());
    }

    private void addNewBeansFromInjectionPoints(Set> newInjectionPoints) {
        for (WeldInjectionPoint injectionPoint : newInjectionPoints) {
            Class rawType = Reflections.getRawType(injectionPoint.getType());
            if (Event.class.equals(rawType)) {
                continue;
            }
            New _new = injectionPoint.getAnnotation(New.class);
            if (_new.value().equals(New.class)) {
                if (rawType.equals(Instance.class)) {
                    // e.g. @Inject @New(ChequePaymentProcessor.class) Instance chequePaymentProcessor;
                    // see WELD-975
                    Type typeParameter = Reflections.getActualTypeArguments(injectionPoint.getType())[0];
                    addNewBeanFromInjecitonPoint(Reflections.getRawType(typeParameter), typeParameter);
                } else {
                    addNewBeanFromInjecitonPoint(rawType, injectionPoint.getType());
                }
            } else {
                addNewBeanFromInjecitonPoint(_new.value(), _new.value());
            }

        }
    }

    private void addNewBeanFromInjecitonPoint(Class rawType, Type baseType) {
        if (getEjbDescriptors().contains(rawType)) {
            newSessionBeanDescriptors.add(getEjbDescriptors().getUnique(rawType));
        } else {
            newManagedBeanClasses.add(classTransformer.loadClass(rawType, baseType));
        }
    }

    public Set> getBeans() {
        return Collections.unmodifiableSet(beans);
    }

    public Set> getDecorators() {
        return Collections.unmodifiableSet(decorators);
    }

    public Set> getInterceptors() {
        return Collections.unmodifiableSet(interceptors);
    }

    public Set> getObservers() {
        return Collections.unmodifiableSet(observers);
    }

    public Set> getUnresolvedDisposalBeans() {
        Set> beans = new HashSet>(allDisposalBeans);
        beans.removeAll(resolvedDisposalBeans);
        return Collections.unmodifiableSet(beans);
    }

    public EjbDescriptors getEjbDescriptors() {
        return ejbDescriptors;
    }

    /**
     * Resolve the disposal method for the given producer method. Any resolved
     * beans will be marked as such for the purpose of validating that all
     * disposal methods are used. For internal use.
     *
     * @param types the types
     * @param qualifiers The binding types to match
     * @param declaringBean declaring bean
     * @return The set of matching disposal methods
     */
    public  Set> resolveDisposalBeans(Set types, Set qualifiers, AbstractClassBean declaringBean) {
        // We can always cache as this is only ever called by Weld where we avoid non-static inner classes for annotation literals
        Set> beans = cast(disposalMethodResolver.resolve(new ResolvableBuilder(beanManager).addTypes(types).addQualifiers(qualifiers).setDeclaringBean(declaringBean).create(), true));
        resolvedDisposalBeans.addAll(beans);
        return Collections.unmodifiableSet(beans);
    }

    private static class WeldMethodKey {

        static  WeldMethodKey of(WeldMethod method) {
            return new WeldMethodKey(method);
        }

        final WeldMethod method;

        WeldMethodKey(WeldMethod meth) {
            this.method = meth;
        }

        @Override
        public boolean equals(Object other) {
            if (other instanceof WeldMethodKey) {
                WeldMethodKey o = (WeldMethodKey) other;
                return AnnotatedTypes.compareAnnotatedCallable(method, o.method);
            }
            return false;
        }

        @Override
        public int hashCode() {
            return method.getJavaMember().hashCode();
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy