001    /**
002     * Copyright (c) 2000-present 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.deploy.hot.IndexerPostProcessorRegistry;
020    import com.liferay.portal.deploy.hot.SchedulerEntryRegistry;
021    import com.liferay.portal.deploy.hot.ServiceWrapperRegistry;
022    import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
023    import com.liferay.portal.kernel.cache.CacheRegistryUtil;
024    import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
025    import com.liferay.portal.kernel.cache.SingleVMPoolUtil;
026    import com.liferay.portal.kernel.cache.ThreadLocalCacheManager;
027    import com.liferay.portal.kernel.dao.db.DBFactoryUtil;
028    import com.liferay.portal.kernel.dao.orm.EntityCacheUtil;
029    import com.liferay.portal.kernel.dao.orm.FinderCacheUtil;
030    import com.liferay.portal.kernel.deploy.DeployManagerUtil;
031    import com.liferay.portal.kernel.deploy.hot.HotDeployUtil;
032    import com.liferay.portal.kernel.exception.LoggedExceptionInInitializerError;
033    import com.liferay.portal.kernel.log.Log;
034    import com.liferay.portal.kernel.log.LogFactoryUtil;
035    import com.liferay.portal.kernel.portlet.PortletBagPool;
036    import com.liferay.portal.kernel.process.ClassPathUtil;
037    import com.liferay.portal.kernel.servlet.DirectServletRegistryUtil;
038    import com.liferay.portal.kernel.servlet.SerializableSessionAttributeListener;
039    import com.liferay.portal.kernel.servlet.ServletContextPool;
040    import com.liferay.portal.kernel.settings.SettingsFactoryUtil;
041    import com.liferay.portal.kernel.template.TemplateResourceLoaderUtil;
042    import com.liferay.portal.kernel.util.CharBufferPool;
043    import com.liferay.portal.kernel.util.ClassLoaderPool;
044    import com.liferay.portal.kernel.util.ClearThreadLocalUtil;
045    import com.liferay.portal.kernel.util.ClearTimerThreadUtil;
046    import com.liferay.portal.kernel.util.InstancePool;
047    import com.liferay.portal.kernel.util.JavaConstants;
048    import com.liferay.portal.kernel.util.MethodCache;
049    import com.liferay.portal.kernel.util.PortalLifecycle;
050    import com.liferay.portal.kernel.util.PortalLifecycleUtil;
051    import com.liferay.portal.kernel.util.ReferenceRegistry;
052    import com.liferay.portal.kernel.util.ReflectionUtil;
053    import com.liferay.portal.kernel.util.ServerDetector;
054    import com.liferay.portal.kernel.util.StringPool;
055    import com.liferay.portal.kernel.util.SystemProperties;
056    import com.liferay.portal.kernel.webcache.WebCachePoolUtil;
057    import com.liferay.portal.module.framework.ModuleFrameworkUtilAdapter;
058    import com.liferay.portal.security.lang.SecurityManagerUtil;
059    import com.liferay.portal.security.permission.PermissionCacheUtil;
060    import com.liferay.portal.servlet.filters.cache.CacheUtil;
061    import com.liferay.portal.spring.bean.BeanReferenceRefreshUtil;
062    import com.liferay.portal.util.ClassLoaderUtil;
063    import com.liferay.portal.util.InitUtil;
064    import com.liferay.portal.util.PropsValues;
065    import com.liferay.portal.util.WebAppPool;
066    import com.liferay.portlet.PortletContextBagPool;
067    import com.liferay.portlet.wiki.util.WikiCacheUtil;
068    
069    import java.beans.PropertyDescriptor;
070    
071    import java.io.File;
072    
073    import java.lang.reflect.Field;
074    
075    import java.util.Map;
076    
077    import javax.servlet.ServletContext;
078    import javax.servlet.ServletContextEvent;
079    
080    import org.springframework.beans.CachedIntrospectionResults;
081    import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
082    import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory;
083    import org.springframework.context.ApplicationContext;
084    import org.springframework.web.context.ContextLoader;
085    import org.springframework.web.context.ContextLoaderListener;
086    
087    /**
088     * @author Michael Young
089     * @author Shuyang Zhou
090     * @author Raymond Aug??
091     */
092    public class PortalContextLoaderListener extends ContextLoaderListener {
093    
094            public static String getPortalServletContextName() {
095                    return _portalServletContextName;
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                            ClearThreadLocalUtil.clearThreadLocal();
110                    }
111                    catch (Exception e) {
112                            _log.error(e, e);
113                    }
114    
115                    try {
116                            ClearTimerThreadUtil.clearTimerThread();
117                    }
118                    catch (Exception e) {
119                            _log.error(e, e);
120                    }
121    
122                    try {
123                            ClearEhcacheThreadUtil.clearEhcacheReplicationThread();
124                    }
125                    catch (Exception e) {
126                            _log.error(e, e);
127                    }
128    
129                    try {
130                            DirectServletRegistryUtil.clearServlets();
131                    }
132                    catch (Exception e) {
133                            _log.error(e, e);
134                    }
135    
136                    try {
137                            HotDeployUtil.reset();
138                    }
139                    catch (Exception e) {
140                            _log.error(e, e);
141                    }
142    
143                    _indexerPostProcessorRegistry.close();
144                    _schedulerEntryRegistry.close();
145                    _serviceWrapperRegistry.close();
146    
147                    try {
148                            ModuleFrameworkUtilAdapter.stopRuntime();
149                    }
150                    catch (Exception e) {
151                            _log.error(e, e);
152                    }
153    
154                    try {
155                            PortalLifecycleUtil.reset();
156                    }
157                    catch (Exception e) {
158                            _log.error(e, e);
159                    }
160    
161                    try {
162                            SettingsFactoryUtil.clearCache();
163                    }
164                    catch (Exception e) {
165                            _log.error(e, e);
166                    }
167    
168                    try {
169                            super.contextDestroyed(servletContextEvent);
170    
171                            try {
172                                    ModuleFrameworkUtilAdapter.stopFramework();
173                            }
174                            catch (Exception e) {
175                                    _log.error(e, e);
176                            }
177                    }
178                    finally {
179                            PortalContextLoaderLifecycleThreadLocal.setDestroying(false);
180    
181                            SecurityManagerUtil.destroy();
182                    }
183            }
184    
185            @Override
186            public void contextInitialized(ServletContextEvent servletContextEvent) {
187                    SystemProperties.reload();
188    
189                    DBFactoryUtil.reset();
190                    DeployManagerUtil.reset();
191                    InstancePool.reset();
192                    MethodCache.reset();
193                    PortalBeanLocatorUtil.reset();
194                    PortletBagPool.reset();
195    
196                    ReferenceRegistry.releaseReferences();
197    
198                    InitUtil.init();
199    
200                    final ServletContext servletContext =
201                            servletContextEvent.getServletContext();
202    
203                    _portalServletContextName = servletContext.getServletContextName();
204    
205                    if (_portalServletContextName == null) {
206                            _portalServletContextName = StringPool.BLANK;
207                    }
208    
209                    if (ServerDetector.isJetty() &&
210                            _portalServletContextName.equals(StringPool.SLASH)) {
211    
212                            _portalServletContextName = StringPool.BLANK;
213                    }
214    
215                    _portalServletContextPath = servletContext.getContextPath();
216    
217                    if (ServerDetector.isWebSphere() &&
218                            _portalServletContextPath.isEmpty()) {
219    
220                            _portalServletContextName = 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 (PropsValues.CACHE_CLEAR_ON_CONTEXT_INITIALIZATION) {
263                            FinderCacheUtil.clearCache();
264                            FinderCacheUtil.clearLocalCache();
265                            EntityCacheUtil.clearCache();
266                            EntityCacheUtil.clearLocalCache();
267                            PermissionCacheUtil.clearCache();
268                            TemplateResourceLoaderUtil.clearCache();
269                            WikiCacheUtil.clearCache(0);
270    
271                            ServletContextPool.clear();
272    
273                            CacheUtil.clearCache();
274                            MultiVMPoolUtil.clear();
275                            SingleVMPoolUtil.clear();
276                            WebCachePoolUtil.clear();
277                    }
278    
279                    ClassLoader portalClassLoader = ClassLoaderUtil.getPortalClassLoader();
280    
281                    ClassLoaderPool.register(_portalServletContextName, portalClassLoader);
282    
283                    ServletContextPool.put(_portalServletContextName, servletContext);
284    
285                    BeanLocatorImpl beanLocatorImpl = new BeanLocatorImpl(
286                            portalClassLoader, applicationContext);
287    
288                    PortalBeanLocatorUtil.setBeanLocator(beanLocatorImpl);
289    
290                    ClassLoader classLoader = portalClassLoader;
291    
292                    while (classLoader != null) {
293                            CachedIntrospectionResults.clearClassLoader(classLoader);
294    
295                            classLoader = classLoader.getParent();
296                    }
297    
298                    AutowireCapableBeanFactory autowireCapableBeanFactory =
299                            applicationContext.getAutowireCapableBeanFactory();
300    
301                    clearFilteredPropertyDescriptorsCache(autowireCapableBeanFactory);
302    
303                    _indexerPostProcessorRegistry = new IndexerPostProcessorRegistry();
304                    _schedulerEntryRegistry = new SchedulerEntryRegistry();
305                    _serviceWrapperRegistry = new ServiceWrapperRegistry();
306    
307                    try {
308                            PortalLifecycleUtil.register(
309                                    new PortalLifecycle() {
310    
311                                            @Override
312                                            public void portalInit() {
313                                                    ModuleFrameworkUtilAdapter.registerContext(
314                                                            servletContext);
315                                            }
316    
317                                            @Override
318                                            public void portalDestroy() {
319                                            }
320    
321                                    });
322    
323                            ModuleFrameworkUtilAdapter.registerContext(applicationContext);
324    
325                            ModuleFrameworkUtilAdapter.startRuntime();
326                    }
327                    catch (Exception e) {
328                            throw new RuntimeException(e);
329                    }
330    
331                    initListeners(servletContext);
332            }
333    
334            protected void clearFilteredPropertyDescriptorsCache(
335                    AutowireCapableBeanFactory autowireCapableBeanFactory) {
336    
337                    try {
338                            Map<Class<?>, PropertyDescriptor[]>
339                                    filteredPropertyDescriptorsCache =
340                                            (Map<Class<?>, PropertyDescriptor[]>)
341                                                    _FILTERED_PROPERTY_DESCRIPTORS_CACHE_FIELD.get(
342                                                            autowireCapableBeanFactory);
343    
344                            filteredPropertyDescriptorsCache.clear();
345                    }
346                    catch (Exception e) {
347                            _log.error(e, e);
348                    }
349            }
350    
351            protected void initListeners(ServletContext servletContext) {
352                    if (PropsValues.SESSION_VERIFY_SERIALIZABLE_ATTRIBUTE) {
353                            servletContext.addListener(
354                                    SerializableSessionAttributeListener.class);
355                    }
356            }
357    
358            private static final Field _FILTERED_PROPERTY_DESCRIPTORS_CACHE_FIELD;
359    
360            private static final Log _log = LogFactoryUtil.getLog(
361                    PortalContextLoaderListener.class);
362    
363            private static String _portalServletContextName = StringPool.BLANK;
364            private static String _portalServletContextPath = StringPool.SLASH;
365    
366            static {
367                    try {
368                            _FILTERED_PROPERTY_DESCRIPTORS_CACHE_FIELD =
369                                    ReflectionUtil.getDeclaredField(
370                                            AbstractAutowireCapableBeanFactory.class,
371                                            "filteredPropertyDescriptorsCache");
372                    }
373                    catch (Exception e) {
374                            throw new LoggedExceptionInInitializerError(e);
375                    }
376            }
377    
378            private IndexerPostProcessorRegistry _indexerPostProcessorRegistry;
379            private SchedulerEntryRegistry _schedulerEntryRegistry;
380            private ServiceWrapperRegistry _serviceWrapperRegistry;
381    
382    }