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