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