001
014
015 package com.liferay.portal.spring.bean;
016
017 import com.liferay.portal.cluster.ClusterableAdvice;
018 import com.liferay.portal.kernel.bean.BeanLocatorException;
019 import com.liferay.portal.kernel.bean.BeanReference;
020 import com.liferay.portal.kernel.bean.IdentifiableBean;
021 import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
022 import com.liferay.portal.kernel.log.Log;
023 import com.liferay.portal.kernel.log.LogFactoryUtil;
024
025 import java.io.PrintWriter;
026 import java.io.StringWriter;
027
028 import java.lang.reflect.Field;
029
030 import java.util.HashMap;
031 import java.util.Map;
032
033 import org.springframework.beans.BeansException;
034 import org.springframework.beans.factory.BeanCreationException;
035 import org.springframework.beans.factory.BeanFactory;
036 import org.springframework.beans.factory.BeanFactoryAware;
037 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
038 import org.springframework.beans.factory.config.BeanPostProcessor;
039 import org.springframework.util.ReflectionUtils;
040
041
045 public class BeanReferenceAnnotationBeanPostProcessor
046 implements BeanFactoryAware, BeanPostProcessor {
047
048 public void destroy() {
049 _beans.clear();
050 }
051
052 public Object postProcessAfterInitialization(Object bean, String beanName)
053 throws BeansException {
054
055 return bean;
056 }
057
058 public Object postProcessBeforeInitialization(Object bean, String beanName)
059 throws BeansException {
060
061 if (bean instanceof IdentifiableBean) {
062 IdentifiableBean identifiableBean = (IdentifiableBean)bean;
063
064 identifiableBean.setBeanIdentifier(beanName);
065 }
066 else if (beanName.endsWith("Service")) {
067 if (_log.isWarnEnabled()) {
068 _log.warn(
069 beanName + " should implement " +
070 IdentifiableBean.class.getName() +
071 " for " + ClusterableAdvice.class.getName());
072 }
073 }
074
075 _autoInject(bean, beanName, bean.getClass());
076
077 return bean;
078 }
079
080 public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
081 _beanFactory = beanFactory;
082 }
083
084 private void _autoInject(
085 Object targetBean, String targetBeanName, Class<?> beanClass) {
086
087 if ((beanClass == null) || beanClass.isInterface()) {
088 return;
089 }
090
091 String className = beanClass.getName();
092
093 if (className.equals(_JAVA_LANG_OBJECT) ||
094 className.startsWith(_ORG_SPRINGFRAMEWORK)) {
095
096 return;
097 }
098
099 Field[] fields = beanClass.getDeclaredFields();
100
101 for (Field field : fields) {
102 BeanReference beanReference = field.getAnnotation(
103 BeanReference.class);
104
105 String referencedBeanName = null;
106 Class<?> referencedBeanType = null;
107
108 if (beanReference != null) {
109 referencedBeanName = beanReference.name();
110 referencedBeanType = beanReference.type();
111 }
112 else {
113 continue;
114 }
115
116 if (!Object.class.equals(referencedBeanType)) {
117 referencedBeanName = referencedBeanType.getName();
118 }
119
120 Object referencedBean = _beans.get(referencedBeanName);
121
122 if (referencedBean == null) {
123 try {
124 referencedBean = _beanFactory.getBean(referencedBeanName);
125 }
126 catch (NoSuchBeanDefinitionException nsbde) {
127 try {
128 referencedBean = PortalBeanLocatorUtil.locate(
129 referencedBeanName);
130 }
131 catch (BeanLocatorException ble) {
132 StringWriter stringWriter = new StringWriter();
133
134 PrintWriter printWriter = new PrintWriter(stringWriter);
135
136 printWriter.print("BeanFactory could not find bean: ");
137
138 nsbde.printStackTrace(printWriter);
139
140 printWriter.print(
141 " and PortalBeanLocator failed with: ");
142 printWriter.append(ble.getMessage());
143
144 printWriter.close();
145
146 throw new BeanLocatorException(
147 stringWriter.toString(), ble);
148 }
149 }
150
151 _beans.put(referencedBeanName, referencedBean);
152 }
153
154 ReflectionUtils.makeAccessible(field);
155
156 try {
157 field.set(targetBean, referencedBean);
158 }
159 catch (Throwable t) {
160 throw new BeanCreationException(
161 targetBeanName, "Could not inject BeanReference fields", t);
162 }
163 }
164
165 _autoInject(targetBean, targetBeanName, beanClass.getSuperclass());
166 }
167
168 private static final String _JAVA_LANG_OBJECT = "java.lang.Object";
169
170 private static final String _ORG_SPRINGFRAMEWORK = "org.springframework";
171
172 private static Log _log = LogFactoryUtil.getLog(
173 BeanReferenceAnnotationBeanPostProcessor.class);
174
175 private BeanFactory _beanFactory;
176 private Map<String, Object> _beans = new HashMap<String, Object>();
177
178 }