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