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