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