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