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

org.pustefixframework.cdi.CDIExtension Maven / Gradle / Ivy

There is a newer version: 0.22.22
Show newest version
/*
 * This file is part of Pustefix.
 *
 * Pustefix is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Pustefix is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Pustefix; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package org.pustefixframework.cdi;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.BeforeBeanDiscovery;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.enterprise.inject.spi.ProcessBean;
import javax.enterprise.inject.spi.ProcessInjectionTarget;
import javax.inject.Named;

public class CDIExtension implements Extension {
    
    private static Map>> cdiBeanRegistry = new HashMap>>();   
    private static Map> unknownBeanRegistry = new HashMap>();
    private static Map beanFactoryAdapters = new HashMap();
    
        
    @SuppressWarnings("unchecked")
    public  void processBean(@Observes ProcessBean procBean, BeanManager manager) {
        //Collect CDI managed beans
        Bean bean = procBean.getBean();
        if(!(bean instanceof SpringBean))  {
            getCDIBeans(manager).add((Bean)bean);
        }
    }

    public void beforeBeanDiscovery(@Observes BeforeBeanDiscovery event, BeanManager manager) {
        synchronized(cdiBeanRegistry) {
            cdiBeanRegistry.put(manager, new ArrayList>());
        }
        unknownBeanRegistry.put(manager, new ArrayList());
        beanFactoryAdapters.put(manager, new BeanFactoryAdapter());
    }
    
    public void afterBeanDiscovery(@Observes AfterBeanDiscovery event, BeanManager manager) {
        //Assume unknown beans will be provided by Spring and bridge beans to CDI
        List beans = getUnknownBeans(manager);
        for(SpringBean bean : beans) {
            Set> found = null;
            if(bean.getName() != null) {
                found = manager.getBeans(bean.getName());
            } 
            if(found == null || found.size() == 0) {
                Annotation[] qualifiers = bean.getQualifiers().toArray(new Annotation[bean.getQualifiers().size()]);
                found = manager.getBeans(bean.getBeanClass(), qualifiers);
            }
            if(found.size() == 0) {
                event.addBean(bean);
            }
        }
    }
    
    public static List> getCDIBeans(BeanManager beanManager) {
        return cdiBeanRegistry.get(beanManager);
    }
    
    public static List getUnknownBeans(BeanManager beanManager) {
        return unknownBeanRegistry.get(beanManager);
    }
    
    public static BeanFactoryAdapter getBeanFactoryAdapter(BeanManager beanManager) {
        return beanFactoryAdapters.get(beanManager);
    }
    
    public void processInjectionTarget(@Observes ProcessInjectionTarget pit, BeanManager beanManager) {
        Set ips = pit.getInjectionTarget().getInjectionPoints();
        for(InjectionPoint ip : ips) {
            
            BeanFactoryAdapter beanFactoryAdapter = beanFactoryAdapters.get(beanManager);
            Class clazz = (Class)ip.getType();
            Annotated annotated = ip.getAnnotated();
            
            String name = null;
            Named named = annotated.getAnnotation(Named.class);
            if(named != null) {
                name = named.value();
            }
            
            AnnotatedType annotatedType = beanManager.createAnnotatedType(clazz);
            Set beanTypes = annotatedType.getTypeClosure();
            
            Set qualifiers = new HashSet();
            Set> stereoTypes = new HashSet>();
            Set annotations = ip.getAnnotated().getAnnotations();
            for(Annotation annotation: annotations) {
                if(beanManager.isQualifier(annotation.annotationType())) {
                    qualifiers.add(annotation);
                } else if(beanManager.isStereotype(annotation.annotationType())) {
                    stereoTypes.add(annotation.annotationType());
                }
            }
            
            SpringBean bean = new SpringBean(beanFactoryAdapter, name, clazz, beanTypes, qualifiers, stereoTypes);
            getUnknownBeans(beanManager).add(bean);
            
        }
    }

}