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