001    /**
002     * Copyright (c) 2000-2011 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.kernel.bean.BeanLocator;
019    import com.liferay.portal.kernel.bean.PortletBeanLocatorUtil;
020    import com.liferay.portal.kernel.concurrent.LockRegistry;
021    import com.liferay.portal.kernel.log.Log;
022    import com.liferay.portal.kernel.log.LogFactoryUtil;
023    import com.liferay.portal.kernel.portlet.PortletClassLoaderUtil;
024    import com.liferay.portal.kernel.util.MethodCache;
025    import com.liferay.portal.kernel.util.StringPool;
026    
027    import java.lang.reflect.Method;
028    
029    import javax.servlet.ServletContext;
030    import javax.servlet.ServletContextEvent;
031    
032    import org.springframework.context.ApplicationContext;
033    import org.springframework.web.context.ContextLoader;
034    import org.springframework.web.context.ContextLoaderListener;
035    import org.springframework.web.context.WebApplicationContext;
036    import org.springframework.web.context.support.WebApplicationContextUtils;
037    
038    /**
039     * @author Brian Wing Shun Chan
040     * @see    PortletApplicationContext
041     * @see    PortletContextLoader
042     */
043    public class PortletContextLoaderListener extends ContextLoaderListener {
044    
045            public static String getLockKey(ServletContext servletContext) {
046                    return getLockKey(servletContext.getContextPath());
047            }
048    
049            public static String getLockKey(String contextPath) {
050                    return PortletContextLoaderListener.class.getName().concat(
051                            StringPool.PERIOD).concat(contextPath);
052            }
053    
054            @Override
055            public void contextDestroyed(ServletContextEvent servletContextEvent) {
056                    ClassLoader classLoader = PortletClassLoaderUtil.getClassLoader();
057    
058                    ServletContext servletContext = servletContextEvent.getServletContext();
059    
060                    try {
061                            Class<?> beanLocatorUtilClass = Class.forName(
062                                    "com.liferay.util.bean.PortletBeanLocatorUtil", true,
063                                    classLoader);
064    
065                            Method setBeanLocatorMethod = beanLocatorUtilClass.getMethod(
066                                    "setBeanLocator", new Class[] {BeanLocator.class});
067    
068                            setBeanLocatorMethod.invoke(
069                                    beanLocatorUtilClass, new Object[] {null});
070    
071                            PortletBeanLocatorUtil.setBeanLocator(
072                                    servletContext.getServletContextName(), null);
073                    }
074                    catch (Exception e) {
075                            if (_log.isWarnEnabled()) {
076                                    _log.warn(e, e);
077                            }
078                    }
079    
080                    super.contextDestroyed(servletContextEvent);
081            }
082    
083            @Override
084            public void contextInitialized(ServletContextEvent servletContextEvent) {
085                    MethodCache.reset();
086    
087                    ServletContext servletContext = servletContextEvent.getServletContext();
088    
089                    Object previousApplicationContext = servletContext.getAttribute(
090                            WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
091    
092                    servletContext.removeAttribute(
093                            WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
094    
095                    try {
096                            super.contextInitialized(servletContextEvent);
097                    }
098                    finally {
099                            String lockKey = getLockKey(servletContext);
100    
101                            LockRegistry.freeLock(lockKey, lockKey, true);
102                    }
103    
104                    PortletBeanFactoryCleaner.readBeans();
105    
106                    ClassLoader classLoader = PortletClassLoaderUtil.getClassLoader();
107    
108                    ApplicationContext applicationContext =
109                            WebApplicationContextUtils.getWebApplicationContext(servletContext);
110    
111                    BeanLocator beanLocator = new BeanLocatorImpl(
112                            classLoader, applicationContext);
113    
114                    try {
115                            Class<?> beanLocatorUtilClass = Class.forName(
116                                    "com.liferay.util.bean.PortletBeanLocatorUtil", true,
117                                    classLoader);
118    
119                            Method setBeanLocatorMethod = beanLocatorUtilClass.getMethod(
120                                    "setBeanLocator", new Class[] {BeanLocator.class});
121    
122                            setBeanLocatorMethod.invoke(
123                                    beanLocatorUtilClass, new Object[] {beanLocator});
124    
125                            PortletBeanLocatorUtil.setBeanLocator(
126                                    servletContext.getServletContextName(), beanLocator);
127                    }
128                    catch (Exception e) {
129                            _log.error(e, e);
130                    }
131    
132                    if (previousApplicationContext == null) {
133                            servletContext.removeAttribute(
134                                    WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
135                    }
136                    else {
137                            servletContext.setAttribute(
138                                    WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
139                                    previousApplicationContext);
140                    }
141            }
142    
143            @Override
144            protected ContextLoader createContextLoader() {
145                    return new PortletContextLoader();
146            }
147    
148            private static Log _log = LogFactoryUtil.getLog(
149                    PortletContextLoaderListener.class);
150    
151    }