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