001    /**
002     * Copyright (c) 2000-2012 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.context;
016    
017    import com.liferay.portal.bean.BeanLocatorImpl;
018    import com.liferay.portal.cache.ehcache.ClearEhcacheThreadUtil;
019    import com.liferay.portal.kernel.bean.BeanLocator;
020    import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
021    import com.liferay.portal.kernel.cache.CacheRegistryUtil;
022    import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
023    import com.liferay.portal.kernel.cache.SingleVMPoolUtil;
024    import com.liferay.portal.kernel.cache.ThreadLocalCacheManager;
025    import com.liferay.portal.kernel.dao.orm.EntityCacheUtil;
026    import com.liferay.portal.kernel.dao.orm.FinderCacheUtil;
027    import com.liferay.portal.kernel.deploy.hot.HotDeployUtil;
028    import com.liferay.portal.kernel.log.Log;
029    import com.liferay.portal.kernel.log.LogFactoryUtil;
030    import com.liferay.portal.kernel.portlet.PortletBagPool;
031    import com.liferay.portal.kernel.process.ClassPathUtil;
032    import com.liferay.portal.kernel.servlet.DirectServletRegistry;
033    import com.liferay.portal.kernel.servlet.ServletContextPool;
034    import com.liferay.portal.kernel.util.CharBufferPool;
035    import com.liferay.portal.kernel.util.ClearThreadLocalUtil;
036    import com.liferay.portal.kernel.util.ClearTimerThreadUtil;
037    import com.liferay.portal.kernel.util.InstancePool;
038    import com.liferay.portal.kernel.util.MethodCache;
039    import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
040    import com.liferay.portal.kernel.util.ReferenceRegistry;
041    import com.liferay.portal.kernel.util.ReflectionUtil;
042    import com.liferay.portal.kernel.webcache.WebCachePoolUtil;
043    import com.liferay.portal.osgi.service.OSGiServiceUtil;
044    import com.liferay.portal.security.permission.PermissionCacheUtil;
045    import com.liferay.portal.servlet.filters.cache.CacheUtil;
046    import com.liferay.portal.util.InitUtil;
047    import com.liferay.portal.util.PropsValues;
048    import com.liferay.portal.util.WebAppPool;
049    import com.liferay.portal.velocity.LiferayResourceCacheUtil;
050    import com.liferay.portlet.PortletContextBagPool;
051    import com.liferay.portlet.wiki.util.WikiCacheUtil;
052    
053    import java.beans.PropertyDescriptor;
054    
055    import java.lang.reflect.Field;
056    
057    import java.util.Map;
058    
059    import javax.servlet.ServletContext;
060    import javax.servlet.ServletContextEvent;
061    
062    import org.springframework.beans.CachedIntrospectionResults;
063    import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
064    import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory;
065    import org.springframework.context.ApplicationContext;
066    import org.springframework.web.context.ContextLoader;
067    import org.springframework.web.context.ContextLoaderListener;
068    
069    /**
070     * @author Michael Young
071     * @author Shuyang Zhou
072     * @author Raymond Augé
073     */
074    public class PortalContextLoaderListener extends ContextLoaderListener {
075    
076            @Override
077            public void contextDestroyed(ServletContextEvent event) {
078                    PortalContextLoaderLifecycleThreadLocal.setDestroying(true);
079    
080                    ThreadLocalCacheManager.destroy();
081    
082                    try {
083                            ClearThreadLocalUtil.clearThreadLocal();
084                    }
085                    catch (Exception e) {
086                            _log.error(e, e);
087                    }
088    
089                    try {
090                            ClearTimerThreadUtil.clearTimerThread();
091                    }
092                    catch (Exception e) {
093                            _log.error(e, e);
094                    }
095    
096                    try {
097                            ClearEhcacheThreadUtil.clearEhcacheReplicationThread();
098                    }
099                    catch (Exception e) {
100                            _log.error(e, e);
101                    }
102    
103                    try {
104                            OSGiServiceUtil.stopRuntime();
105                    }
106                    catch (Exception e) {
107                            _log.error(e, e);
108                    }
109    
110                    try {
111                            super.contextDestroyed(event);
112    
113                            try {
114                                    OSGiServiceUtil.stopFramework();
115                            }
116                            catch (Exception e) {
117                                    _log.error(e, e);
118                            }
119                    }
120                    finally {
121                            PortalContextLoaderLifecycleThreadLocal.setDestroying(false);
122                    }
123            }
124    
125            @Override
126            public void contextInitialized(ServletContextEvent servletContextEvent) {
127                    HotDeployUtil.reset();
128                    InstancePool.reset();
129                    MethodCache.reset();
130                    PortletBagPool.reset();
131    
132                    ReferenceRegistry.releaseReferences();
133    
134                    InitUtil.init();
135    
136                    ServletContext servletContext = servletContextEvent.getServletContext();
137    
138                    ClassPathUtil.initializeClassPaths(servletContext);
139    
140                    DirectServletRegistry.clearServlets();
141    
142                    CacheRegistryUtil.clear();
143                    CharBufferPool.cleanUp();
144                    PortletContextBagPool.clear();
145                    WebAppPool.clear();
146    
147                    if (PropsValues.OSGI_ENABLED) {
148                            try {
149                                    OSGiServiceUtil.init();
150                            }
151                            catch (Exception e) {
152                                    _log.error(e, e);
153                            }
154                    }
155    
156                    PortalContextLoaderLifecycleThreadLocal.setInitializing(true);
157    
158                    try {
159                            super.contextInitialized(servletContextEvent);
160                    }
161                    finally {
162                            PortalContextLoaderLifecycleThreadLocal.setInitializing(false);
163                    }
164    
165                    FinderCacheUtil.clearCache();
166                    FinderCacheUtil.clearLocalCache();
167                    EntityCacheUtil.clearCache();
168                    EntityCacheUtil.clearLocalCache();
169                    LiferayResourceCacheUtil.clear();
170                    PermissionCacheUtil.clearCache();
171                    PermissionCacheUtil.clearLocalCache();
172                    WikiCacheUtil.clearCache(0);
173    
174                    ServletContextPool.clear();
175    
176                    CacheUtil.clearCache();
177                    MultiVMPoolUtil.clear();
178                    SingleVMPoolUtil.clear();
179                    WebCachePoolUtil.clear();
180    
181                    ApplicationContext applicationContext =
182                            ContextLoader.getCurrentWebApplicationContext();
183    
184                    ClassLoader portalClassLoader = PortalClassLoaderUtil.getClassLoader();
185    
186                    BeanLocator beanLocator = new BeanLocatorImpl(
187                            portalClassLoader, applicationContext);
188    
189                    PortalBeanLocatorUtil.setBeanLocator(beanLocator);
190    
191                    ClassLoader classLoader = portalClassLoader;
192    
193                    while (classLoader != null) {
194                            CachedIntrospectionResults.clearClassLoader(classLoader);
195    
196                            classLoader = classLoader.getParent();
197                    }
198    
199                    AutowireCapableBeanFactory autowireCapableBeanFactory =
200                            applicationContext.getAutowireCapableBeanFactory();
201    
202                    clearFilteredPropertyDescriptorsCache(autowireCapableBeanFactory);
203    
204                    if (PropsValues.OSGI_ENABLED) {
205                            try {
206                                    OSGiServiceUtil.registerContext(servletContext);
207                                    OSGiServiceUtil.registerContext(applicationContext);
208    
209                                    OSGiServiceUtil.start();
210                            }
211                            catch (Exception e) {
212                                    _log.error(e, e);
213                            }
214                    }
215            }
216    
217            protected void clearFilteredPropertyDescriptorsCache(
218                    AutowireCapableBeanFactory autowireCapableBeanFactory) {
219    
220                    try {
221                            Map<Class<?>, PropertyDescriptor[]>
222                                    filteredPropertyDescriptorsCache =
223                                            (Map<Class<?>, PropertyDescriptor[]>)
224                                                    _filteredPropertyDescriptorsCacheField.get(
225                                                            autowireCapableBeanFactory);
226    
227                            filteredPropertyDescriptorsCache.clear();
228                    }
229                    catch (Exception e) {
230                            _log.error(e, e);
231                    }
232            }
233    
234            private static Log _log = LogFactoryUtil.getLog(
235                    PortalContextLoaderListener.class);
236    
237            private static Field _filteredPropertyDescriptorsCacheField;
238    
239            static {
240                    try {
241                            _filteredPropertyDescriptorsCacheField =
242                                    ReflectionUtil.getDeclaredField(
243                                            AbstractAutowireCapableBeanFactory.class,
244                                            "filteredPropertyDescriptorsCache");
245                    }
246                    catch (Exception e) {
247                            _log.error(e, e);
248                    }
249            }
250    
251    }