001
014
015 package com.liferay.portal.spring.bean;
016
017 import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020
021 import java.lang.reflect.Field;
022
023 import java.util.ArrayList;
024 import java.util.IdentityHashMap;
025 import java.util.List;
026 import java.util.Map;
027
028 import org.springframework.beans.factory.BeanFactory;
029 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
030
031
034 public class BeanReferenceRefreshUtil {
035
036 public static void refresh(BeanFactory beanFactory) throws Exception {
037 BeanRegistrations beanRegistrations = _registeredRefreshPoints.remove(
038 beanFactory);
039
040 if (beanRegistrations == null) {
041 return;
042 }
043
044 beanRegistrations.refresh();
045 }
046
047 public static void registerRefreshPoint(
048 BeanFactory beanFactory, Object targetBean, Field field,
049 String referencedBeanName) {
050
051 BeanRegistrations beanRegistrations = _registeredRefreshPoints.get(
052 beanFactory);
053
054 if (beanRegistrations == null) {
055 beanRegistrations = new BeanRegistrations(beanFactory);
056
057 _registeredRefreshPoints.put(beanFactory, beanRegistrations);
058 }
059
060 beanRegistrations.addRefreshPoint(
061 targetBean, field, referencedBeanName);
062 }
063
064 public interface PACL {
065
066 public Object getNewReferencedBean(
067 String referencedBeanName, BeanFactory beanFactory);
068
069 }
070
071 private static final Log _log = LogFactoryUtil.getLog(
072 BeanReferenceRefreshUtil.class);
073
074 private static final PACL _pacl = new NoPACL();
075 private static final Map<BeanFactory, BeanRegistrations>
076 _registeredRefreshPoints = new IdentityHashMap<>();
077
078 private static class BeanRegistrations {
079
080 public BeanRegistrations(BeanFactory beanFactory) {
081 _beanFactory = beanFactory;
082 }
083
084 public void addRefreshPoint(
085 Object bean, Field field, String referencedBeanName) {
086
087 List<RefreshPoint> refreshPoints = _beansToRefresh.get(bean);
088
089 if (refreshPoints == null) {
090 refreshPoints = new ArrayList<>();
091
092 _beansToRefresh.put(bean, refreshPoints);
093 }
094
095 refreshPoints.add(new RefreshPoint(field, referencedBeanName));
096 }
097
098 public void refresh() throws Exception {
099 for (Map.Entry<Object, List<RefreshPoint>> entry :
100 _beansToRefresh.entrySet()) {
101
102 _refresh(entry.getKey(), entry.getValue());
103 }
104 }
105
106 private void _refresh(
107 Object targetBean, List<RefreshPoint> refreshPoints)
108 throws Exception {
109
110 for (RefreshPoint refreshPoint : refreshPoints) {
111 _refresh(targetBean, refreshPoint);
112 }
113 }
114
115 private void _refresh(Object targetBean, RefreshPoint refreshPoint)
116 throws Exception {
117
118 Field field = refreshPoint._field;
119
120 Object oldReferenceBean = field.get(targetBean);
121
122 String referencedBeanName = refreshPoint._referencedBeanName;
123
124 Object newReferencedBean = _pacl.getNewReferencedBean(
125 referencedBeanName, _beanFactory);
126
127 if (oldReferenceBean == newReferencedBean) {
128 return;
129 }
130
131 field.set(targetBean, newReferencedBean);
132
133 if (_log.isDebugEnabled()) {
134 _log.debug(
135 "Refreshed field " + field + " with old value " +
136 oldReferenceBean + " with new value " +
137 newReferencedBean + " on bean " + targetBean);
138 }
139 }
140
141 private final BeanFactory _beanFactory;
142 private final Map<Object, List<RefreshPoint>>
143 _beansToRefresh = new IdentityHashMap<>();
144
145 }
146
147 private static class NoPACL implements PACL {
148
149 @Override
150 public Object getNewReferencedBean(
151 String referencedBeanName, BeanFactory beanFactory) {
152
153 try {
154 return beanFactory.getBean(referencedBeanName);
155 }
156 catch (NoSuchBeanDefinitionException nsbde) {
157 if (_log.isInfoEnabled()) {
158 _log.info(
159 "Bean " + referencedBeanName + " may be defined in " +
160 "the portal");
161 }
162
163 return PortalBeanLocatorUtil.locate(referencedBeanName);
164 }
165 }
166
167 }
168
169 private static class RefreshPoint {
170
171 public RefreshPoint(Field field, String referencedBeanName) {
172 _field = field;
173 _referencedBeanName = referencedBeanName;
174 }
175
176 private final Field _field;
177 private final String _referencedBeanName;
178
179 }
180
181 }