001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.spring.bean;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.security.lang.DoPrivilegedFactory;
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    
030    /**
031     * @author Shuyang Zhou
032     */
033    public class BeanReferenceRefreshUtil {
034    
035            public static void refresh(BeanFactory beanFactory) throws Exception {
036                    for (Map.Entry<Object, List<RefreshPoint>> entry :
037                                    _registeredRefreshPoints.entrySet()) {
038    
039                            _refresh(beanFactory, entry.getKey(), entry.getValue());
040                    }
041    
042                    _registeredRefreshPoints.clear();
043            }
044    
045            public static void registerRefreshPoint(
046                    Object targetBean, Field field, String referencedBeanName) {
047    
048                    List<RefreshPoint> refreshPoints = _registeredRefreshPoints.get(
049                            targetBean);
050    
051                    if (refreshPoints == null) {
052                            refreshPoints = new ArrayList<RefreshPoint>();
053    
054                            _registeredRefreshPoints.put(targetBean, refreshPoints);
055                    }
056    
057                    refreshPoints.add(new RefreshPoint(field, referencedBeanName));
058            }
059    
060            private static void _refresh(
061                            BeanFactory beanFactory, Object targetBean,
062                            List<RefreshPoint> refreshPoints)
063                    throws Exception {
064    
065                    for (RefreshPoint refreshPoint : refreshPoints) {
066                            _refresh(beanFactory, targetBean, refreshPoint);
067                    }
068            }
069    
070            private static void _refresh(
071                            BeanFactory beanFactory, Object targetBean,
072                            RefreshPoint refreshPoint)
073                    throws Exception {
074    
075                    Field field = refreshPoint._field;
076    
077                    Object oldReferenceBean = field.get(targetBean);
078    
079                    String referencedBeanName = refreshPoint._referencedBeanName;
080    
081                    Object newReferencedBean = beanFactory.getBean(referencedBeanName);
082    
083                    Object doPrivilegedBean = _doPrivilegedBeans.get(newReferencedBean);
084    
085                    if ((doPrivilegedBean == null) &&
086                            DoPrivilegedFactory.isEarlyBeanReference(referencedBeanName)) {
087    
088                            doPrivilegedBean = DoPrivilegedFactory.wrap(newReferencedBean);
089    
090                            _doPrivilegedBeans.put(newReferencedBean, doPrivilegedBean);
091                    }
092    
093                    if (doPrivilegedBean != null) {
094                            newReferencedBean = doPrivilegedBean;
095                    }
096    
097                    if (oldReferenceBean == newReferencedBean) {
098                            return;
099                    }
100    
101                    field.set(targetBean, newReferencedBean);
102    
103                    if (_log.isDebugEnabled()) {
104                            _log.debug(
105                                    "Refreshed field " + field + " with old value " +
106                                            oldReferenceBean + " with new value " + newReferencedBean +
107                                                    " on bean " + targetBean);
108                    }
109            }
110    
111            private static Log _log = LogFactoryUtil.getLog(
112                    BeanReferenceRefreshUtil.class);
113    
114            private static Map<Object, Object> _doPrivilegedBeans =
115                    new IdentityHashMap<Object, Object>();
116            private static Map<Object, List<RefreshPoint>> _registeredRefreshPoints =
117                    new IdentityHashMap<Object, List<RefreshPoint>>();
118    
119            private static class RefreshPoint {
120    
121                    public RefreshPoint(Field field, String referencedBeanName) {
122                            _field = field;
123                            _referencedBeanName = referencedBeanName;
124                    }
125    
126                    private Field _field;
127                    private String _referencedBeanName;
128    
129            }
130    
131    }