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.ServerDetector;
047    import com.liferay.portal.kernel.util.StringPool;
048    import com.liferay.portal.kernel.util.SystemProperties;
049    import com.liferay.portal.kernel.webcache.WebCachePoolUtil;
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                            SecurityManagerUtil.destroy();
164                    }
165            }
166    
167            @Override
168            public void contextInitialized(ServletContextEvent servletContextEvent) {
169                    SystemProperties.reload();
170    
171                    DBFactoryUtil.reset();
172                    DeployManagerUtil.reset();
173                    InstancePool.reset();
174                    MethodCache.reset();
175                    PortalBeanLocatorUtil.reset();
176                    PortletBagPool.reset();
177    
178                    ReferenceRegistry.releaseReferences();
179    
180                    InitUtil.init();
181    
182                    ServletContext servletContext = servletContextEvent.getServletContext();
183    
184                    _portalServlerContextName = servletContext.getServletContextName();
185    
186                    if (_portalServlerContextName == null) {
187                            _portalServlerContextName = StringPool.BLANK;
188                    }
189    
190                    if (ServerDetector.isJetty() &&
191                            _portalServlerContextName.equals(StringPool.SLASH)) {
192    
193                            _portalServlerContextName = StringPool.BLANK;
194                    }
195    
196                    _portalServletContextPath = servletContext.getContextPath();
197    
198                    if (ServerDetector.isWebSphere() &&
199                            _portalServletContextPath.isEmpty()) {
200    
201                            _portalServlerContextName = StringPool.BLANK;
202                    }
203    
204                    ClassPathUtil.initializeClassPaths(servletContext);
205    
206                    CacheRegistryUtil.clear();
207                    CharBufferPool.cleanUp();
208                    PortletContextBagPool.clear();
209                    WebAppPool.clear();
210    
211                    File tempDir = (File)servletContext.getAttribute(
212                            JavaConstants.JAVAX_SERVLET_CONTEXT_TEMPDIR);
213    
214                    PropsValues.LIFERAY_WEB_PORTAL_CONTEXT_TEMPDIR =
215                            tempDir.getAbsolutePath();
216    
217                    try {
218                            ModuleFrameworkUtilAdapter.startFramework();
219                    }
220                    catch (Exception e) {
221                            throw new RuntimeException(e);
222                    }
223    
224                    PortalContextLoaderLifecycleThreadLocal.setInitializing(true);
225    
226                    try {
227                            super.contextInitialized(servletContextEvent);
228                    }
229                    finally {
230                            PortalContextLoaderLifecycleThreadLocal.setInitializing(false);
231                    }
232    
233                    ApplicationContext applicationContext =
234                            ContextLoader.getCurrentWebApplicationContext();
235    
236                    try {
237                            BeanReferenceRefreshUtil.refresh(applicationContext);
238                    }
239                    catch (Exception e) {
240                            _log.error(e, e);
241                    }
242    
243                    FinderCacheUtil.clearCache();
244                    FinderCacheUtil.clearLocalCache();
245                    EntityCacheUtil.clearCache();
246                    EntityCacheUtil.clearLocalCache();
247                    PermissionCacheUtil.clearCache();
248                    PermissionCacheUtil.clearLocalCache();
249                    TemplateResourceLoaderUtil.clearCache();
250                    WikiCacheUtil.clearCache(0);
251    
252                    ServletContextPool.clear();
253    
254                    CacheUtil.clearCache();
255                    MultiVMPoolUtil.clear();
256                    SingleVMPoolUtil.clear();
257                    WebCachePoolUtil.clear();
258    
259                    ClassLoader portalClassLoader = ClassLoaderUtil.getPortalClassLoader();
260    
261                    ClassLoaderPool.register(_portalServlerContextName, portalClassLoader);
262    
263                    ServletContextPool.put(_portalServlerContextName, servletContext);
264    
265                    BeanLocatorImpl beanLocatorImpl = new BeanLocatorImpl(
266                            portalClassLoader, applicationContext);
267    
268                    PortalBeanLocatorUtil.setBeanLocator(beanLocatorImpl);
269    
270                    ClassLoader classLoader = portalClassLoader;
271    
272                    while (classLoader != null) {
273                            CachedIntrospectionResults.clearClassLoader(classLoader);
274    
275                            classLoader = classLoader.getParent();
276                    }
277    
278                    AutowireCapableBeanFactory autowireCapableBeanFactory =
279                            applicationContext.getAutowireCapableBeanFactory();
280    
281                    clearFilteredPropertyDescriptorsCache(autowireCapableBeanFactory);
282    
283                    try {
284                            ModuleFrameworkUtilAdapter.registerContext(applicationContext);
285                            ModuleFrameworkUtilAdapter.registerContext(servletContext);
286    
287                            ModuleFrameworkUtilAdapter.startRuntime();
288                    }
289                    catch (Exception e) {
290                            throw new RuntimeException(e);
291                    }
292            }
293    
294            protected void clearFilteredPropertyDescriptorsCache(
295                    AutowireCapableBeanFactory autowireCapableBeanFactory) {
296    
297                    try {
298                            Map<Class<?>, PropertyDescriptor[]>
299                                    filteredPropertyDescriptorsCache =
300                                            (Map<Class<?>, PropertyDescriptor[]>)
301                                                    _filteredPropertyDescriptorsCacheField.get(
302                                                            autowireCapableBeanFactory);
303    
304                            filteredPropertyDescriptorsCache.clear();
305                    }
306                    catch (Exception e) {
307                            _log.error(e, e);
308                    }
309            }
310    
311            private static Log _log = LogFactoryUtil.getLog(
312                    PortalContextLoaderListener.class);
313    
314            private static Field _filteredPropertyDescriptorsCacheField;
315            private static String _portalServlerContextName = StringPool.BLANK;
316            private static String _portalServletContextPath = StringPool.SLASH;
317    
318            static {
319                    try {
320                            _filteredPropertyDescriptorsCacheField =
321                                    ReflectionUtil.getDeclaredField(
322                                            AbstractAutowireCapableBeanFactory.class,
323                                            "filteredPropertyDescriptorsCache");
324                    }
325                    catch (Exception e) {
326                            _log.error(e, e);
327                    }
328            }
329    
330    }