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