1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.portal.spring.annotation;
16  
17  import com.liferay.portal.kernel.annotation.BeanReference;
18  import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
19  
20  import java.lang.reflect.Field;
21  
22  import java.util.HashMap;
23  import java.util.Map;
24  
25  import org.springframework.beans.BeansException;
26  import org.springframework.beans.factory.BeanCreationException;
27  import org.springframework.beans.factory.BeanFactory;
28  import org.springframework.beans.factory.BeanFactoryAware;
29  import org.springframework.beans.factory.NoSuchBeanDefinitionException;
30  import org.springframework.beans.factory.config.BeanPostProcessor;
31  import org.springframework.util.ReflectionUtils;
32  
33  /**
34   * <a href="BeanReferenceAnnotationBeanPostProcessor.java.html"><b><i>View
35   * Source</i></b></a>
36   *
37   * @author Michael Young
38   * @author Shuyang Zhou
39   */
40  public class BeanReferenceAnnotationBeanPostProcessor
41      implements BeanFactoryAware, BeanPostProcessor {
42  
43      public void destroy() {
44          _beans.clear();
45      }
46  
47      public Object postProcessAfterInitialization(Object bean, String beanName)
48          throws BeansException {
49  
50          return bean;
51      }
52  
53      public Object postProcessBeforeInitialization(Object bean, String beanName)
54          throws BeansException {
55  
56          _autoInject(bean, beanName, bean.getClass());
57  
58          return bean;
59      }
60  
61      public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
62          _beanFactory = beanFactory;
63      }
64  
65      private void _autoInject(
66          Object targetBean, String targetBeanName, Class<?> beanClass) {
67  
68          if ((beanClass == null) || beanClass.isInterface()) {
69              return;
70          }
71  
72          String className = beanClass.getName();
73  
74          if (className.equals(_JAVA_LANG_OBJECT) ||
75              className.startsWith(_ORG_SPRINGFRAMEWORK)) {
76  
77              return;
78          }
79  
80          Field[] fields = beanClass.getDeclaredFields();
81  
82          for (Field field : fields) {
83              BeanReference beanReference = field.getAnnotation(
84                  BeanReference.class);
85  
86              if (beanReference == null) {
87                  continue;
88              }
89  
90              String referencedBeanName = beanReference.name();
91  
92              Class<?> referencedBeanType = beanReference.type();
93  
94              if (!Object.class.equals(referencedBeanType)) {
95                  referencedBeanName = referencedBeanType.getName();
96              }
97  
98              Object referencedBean = _beans.get(referencedBeanName);
99  
100             if (referencedBean == null) {
101                 try {
102                     referencedBean = _beanFactory.getBean(referencedBeanName);
103                 }
104                 catch (NoSuchBeanDefinitionException nsbde) {
105                     referencedBean = PortalBeanLocatorUtil.locate(
106                         referencedBeanName);
107                 }
108 
109                 _beans.put(referencedBeanName, referencedBean);
110             }
111 
112             ReflectionUtils.makeAccessible(field);
113 
114             try {
115                 field.set(targetBean, referencedBean);
116             }
117             catch (Throwable t) {
118                 throw new BeanCreationException(
119                     targetBeanName, "Could not inject BeanReference fields",
120                     t);
121             }
122         }
123 
124         _autoInject(targetBean, targetBeanName, beanClass.getSuperclass());
125 
126         return;
127     }
128 
129     private static String _JAVA_LANG_OBJECT = "java.lang.Object";
130 
131     private static String _ORG_SPRINGFRAMEWORK = "org.springframework";
132 
133     private BeanFactory _beanFactory;
134     private Map<String, Object> _beans = new HashMap<String, Object>();
135 
136 }