001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.spring.annotation;
016    
017    import com.liferay.portal.kernel.annotation.BeanReference;
018    import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
019    
020    import java.lang.reflect.Field;
021    
022    import java.util.HashMap;
023    import java.util.Map;
024    
025    import org.springframework.beans.BeansException;
026    import org.springframework.beans.factory.BeanCreationException;
027    import org.springframework.beans.factory.BeanFactory;
028    import org.springframework.beans.factory.BeanFactoryAware;
029    import org.springframework.beans.factory.NoSuchBeanDefinitionException;
030    import org.springframework.beans.factory.config.BeanPostProcessor;
031    import org.springframework.util.ReflectionUtils;
032    
033    /**
034     * @author Michael Young
035     * @author Shuyang Zhou
036     */
037    public class BeanReferenceAnnotationBeanPostProcessor
038            implements BeanFactoryAware, BeanPostProcessor {
039    
040            public Object postProcessAfterInitialization(Object bean, String beanName)
041                    throws BeansException {
042    
043                    return bean;
044            }
045    
046            public Object postProcessBeforeInitialization(Object bean, String beanName)
047                    throws BeansException {
048    
049                    _autoInject(bean, beanName, bean.getClass());
050    
051                    return bean;
052            }
053    
054            public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
055                    _beanFactory = beanFactory;
056            }
057    
058            private void _autoInject(
059                    Object targetBean, String targetBeanName, Class<?> beanClass) {
060    
061                    if ((beanClass == null) || beanClass.isInterface()) {
062                            return;
063                    }
064    
065                    String className = beanClass.getName();
066    
067                    if (className.equals(_JAVA_LANG_OBJECT) ||
068                            className.startsWith(_ORG_SPRINGFRAMEWORK)) {
069    
070                            return;
071                    }
072    
073                    Field[] fields = beanClass.getDeclaredFields();
074    
075                    for (Field field : fields) {
076                            BeanReference beanReference = field.getAnnotation(
077                                    BeanReference.class);
078    
079                            if (beanReference == null) {
080                                    continue;
081                            }
082    
083                            String referencedBeanName = beanReference.name();
084    
085                            Class<?> referencedBeanType = beanReference.type();
086    
087                            if (!Object.class.equals(referencedBeanType)) {
088                                    referencedBeanName = referencedBeanType.getName();
089                            }
090    
091                            Object referencedBean = _beans.get(referencedBeanName);
092    
093                            if (referencedBean == null) {
094                                    try {
095                                            referencedBean = _beanFactory.getBean(referencedBeanName);
096                                    }
097                                    catch (NoSuchBeanDefinitionException nsbde) {
098                                            referencedBean = PortalBeanLocatorUtil.locate(
099                                                    referencedBeanName);
100                                    }
101    
102                                    _beans.put(referencedBeanName, referencedBean);
103                            }
104    
105                            ReflectionUtils.makeAccessible(field);
106    
107                            try {
108                                    field.set(targetBean, referencedBean);
109                            }
110                            catch (Throwable t) {
111                                    throw new BeanCreationException(
112                                            targetBeanName, "Could not inject BeanReference fields",
113                                            t);
114                            }
115                    }
116    
117                    _autoInject(targetBean, targetBeanName, beanClass.getSuperclass());
118    
119                    return;
120            }
121    
122            private static String _JAVA_LANG_OBJECT = "java.lang.Object";
123    
124            private static String _ORG_SPRINGFRAMEWORK = "org.springframework";
125    
126            private BeanFactory _beanFactory;
127            private Map<String, Object> _beans = new HashMap<String, Object>();
128    
129    }