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