001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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                    Thread currentThread = Thread.currentThread();
184    
185                    SystemProperties.load(currentThread.getContextClassLoader());
186    
187                    DBFactoryUtil.reset();
188                    DeployManagerUtil.reset();
189                    InstancePool.reset();
190                    MethodCache.reset();
191                    PortalBeanLocatorUtil.reset();
192                    PortletBagPool.reset();
193    
194                    ReferenceRegistry.releaseReferences();
195    
196                    InitUtil.init();
197    
198                    ServletContext servletContext = servletContextEvent.getServletContext();
199    
200                    _portalServlerContextName = servletContext.getServletContextName();
201    
202                    if (_portalServlerContextName == null) {
203                            _portalServlerContextName = StringPool.BLANK;
204                    }
205    
206                    if (ServerDetector.isJetty() &&
207                            _portalServlerContextName.equals(StringPool.SLASH)) {
208    
209                            _portalServlerContextName = StringPool.BLANK;
210                    }
211    
212                    _portalServletContextPath = servletContext.getContextPath();
213    
214                    if (ServerDetector.isWebSphere() &&
215                            _portalServletContextPath.isEmpty()) {
216    
217                            _portalServlerContextName = StringPool.BLANK;
218                    }
219    
220                    ClassPathUtil.initializeClassPaths(servletContext);
221    
222                    CacheRegistryUtil.clear();
223                    CharBufferPool.cleanUp();
224                    PortletContextBagPool.clear();
225                    WebAppPool.clear();
226    
227                    File tempDir = (File)servletContext.getAttribute(
228                            JavaConstants.JAVAX_SERVLET_CONTEXT_TEMPDIR);
229    
230                    PropsValues.LIFERAY_WEB_PORTAL_CONTEXT_TEMPDIR =
231                            tempDir.getAbsolutePath();
232    
233                    try {
234                            ModuleFrameworkUtilAdapter.startFramework();
235                    }
236                    catch (Exception e) {
237                            throw new RuntimeException(e);
238                    }
239    
240                    PortalContextLoaderLifecycleThreadLocal.setInitializing(true);
241    
242                    try {
243                            super.contextInitialized(servletContextEvent);
244                    }
245                    finally {
246                            PortalContextLoaderLifecycleThreadLocal.setInitializing(false);
247                    }
248    
249                    ApplicationContext applicationContext =
250                            ContextLoader.getCurrentWebApplicationContext();
251    
252                    try {
253                            BeanReferenceRefreshUtil.refresh(applicationContext);
254                    }
255                    catch (Exception e) {
256                            _log.error(e, e);
257                    }
258    
259                    if (CACHE_CLEAR_ON_CONTEXT_INITIALIZATION) {
260                            FinderCacheUtil.clearCache();
261                            FinderCacheUtil.clearLocalCache();
262                            EntityCacheUtil.clearCache();
263                            EntityCacheUtil.clearLocalCache();
264                            PermissionCacheUtil.clearCache();
265                            PermissionCacheUtil.clearLocalCache();
266                            TemplateResourceLoaderUtil.clearCache();
267                            WikiCacheUtil.clearCache(0);
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(_portalServlerContextName, portalClassLoader);
280    
281                    ServletContextPool.put(_portalServlerContextName, 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                    try {
302                            ModuleFrameworkUtilAdapter.registerContext(applicationContext);
303                            ModuleFrameworkUtilAdapter.registerContext(servletContext);
304    
305                            ModuleFrameworkUtilAdapter.startRuntime();
306                    }
307                    catch (Exception e) {
308                            throw new RuntimeException(e);
309                    }
310            }
311    
312            protected void clearFilteredPropertyDescriptorsCache(
313                    AutowireCapableBeanFactory autowireCapableBeanFactory) {
314    
315                    try {
316                            Map<Class<?>, PropertyDescriptor[]>
317                                    filteredPropertyDescriptorsCache =
318                                            (Map<Class<?>, PropertyDescriptor[]>)
319                                                    _filteredPropertyDescriptorsCacheField.get(
320                                                            autowireCapableBeanFactory);
321    
322                            filteredPropertyDescriptorsCache.clear();
323                    }
324                    catch (Exception e) {
325                            _log.error(e, e);
326                    }
327            }
328    
329            private static Log _log = LogFactoryUtil.getLog(
330                    PortalContextLoaderListener.class);
331    
332            private static Field _filteredPropertyDescriptorsCacheField;
333            private static String _portalServlerContextName = StringPool.BLANK;
334            private static String _portalServletContextPath = StringPool.SLASH;
335    
336            static {
337                    try {
338                            _filteredPropertyDescriptorsCacheField =
339                                    ReflectionUtil.getDeclaredField(
340                                            AbstractAutowireCapableBeanFactory.class,
341                                            "filteredPropertyDescriptorsCache");
342                    }
343                    catch (Exception e) {
344                            _log.error(e, e);
345                    }
346            }
347    
348    }