001    /**
002     * Copyright (c) 2000-2012 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.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.security.lang.PortalSecurityManagerThreadLocal;
025    import com.liferay.portal.security.pacl.PACLPolicy;
026    import com.liferay.portal.security.pacl.PACLPolicyManager;
027    
028    import java.lang.reflect.Method;
029    
030    import javax.servlet.ServletContext;
031    import javax.servlet.ServletContextEvent;
032    
033    import org.springframework.context.ApplicationContext;
034    import org.springframework.web.context.ConfigurableWebApplicationContext;
035    import org.springframework.web.context.ContextLoaderListener;
036    import org.springframework.web.context.WebApplicationContext;
037    import org.springframework.web.context.support.WebApplicationContextUtils;
038    
039    /**
040     * @author Brian Wing Shun Chan
041     * @see    PortletApplicationContext
042     */
043    public class PortletContextLoaderListener extends ContextLoaderListener {
044    
045            @Override
046            public void contextDestroyed(ServletContextEvent servletContextEvent) {
047                    ClassLoader classLoader = PortletClassLoaderUtil.getClassLoader();
048    
049                    ServletContext servletContext = servletContextEvent.getServletContext();
050    
051                    try {
052                            Class<?> beanLocatorUtilClass = Class.forName(
053                                    "com.liferay.util.bean.PortletBeanLocatorUtil", true,
054                                    classLoader);
055    
056                            Method setBeanLocatorMethod = beanLocatorUtilClass.getMethod(
057                                    "setBeanLocator", new Class[] {BeanLocator.class});
058    
059                            setBeanLocatorMethod.invoke(
060                                    beanLocatorUtilClass, new Object[] {null});
061    
062                            PortletBeanLocatorUtil.setBeanLocator(
063                                    servletContext.getServletContextName(), null);
064                    }
065                    catch (Exception e) {
066                            if (_log.isWarnEnabled()) {
067                                    _log.warn(e, e);
068                            }
069                    }
070    
071                    super.contextDestroyed(servletContextEvent);
072            }
073    
074            @Override
075            public void contextInitialized(ServletContextEvent servletContextEvent) {
076                    MethodCache.reset();
077    
078                    ServletContext servletContext = servletContextEvent.getServletContext();
079    
080                    Object previousApplicationContext = servletContext.getAttribute(
081                            WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
082    
083                    servletContext.removeAttribute(
084                            WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
085    
086                    ClassLoader classLoader = PortletClassLoaderUtil.getClassLoader();
087    
088                    PACLPolicy previousPACLPolicy =
089                            PortalSecurityManagerThreadLocal.getPACLPolicy();
090    
091                    try {
092                            PACLPolicy paclPolicy = PACLPolicyManager.getPACLPolicy(
093                                    classLoader);
094    
095                            PortalSecurityManagerThreadLocal.setPACLPolicy(paclPolicy);
096    
097                            super.contextInitialized(servletContextEvent);
098                    }
099                    finally {
100                            PortalSecurityManagerThreadLocal.setPACLPolicy(previousPACLPolicy);
101                    }
102    
103                    PortletBeanFactoryCleaner.readBeans();
104    
105                    ApplicationContext applicationContext =
106                            WebApplicationContextUtils.getWebApplicationContext(servletContext);
107    
108                    BeanLocatorImpl beanLocatorImpl = new BeanLocatorImpl(
109                            classLoader, applicationContext);
110    
111                    beanLocatorImpl.setPACLServletContextName(
112                            servletContext.getServletContextName());
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[] {beanLocatorImpl});
124    
125                            PortletBeanLocatorUtil.setBeanLocator(
126                                    servletContext.getServletContextName(), beanLocatorImpl);
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 void customizeContext(
145                    ServletContext servletContext,
146                    ConfigurableWebApplicationContext configurableWebApplicationContext) {
147    
148                    String configLocation = servletContext.getInitParameter(
149                            _PORTAL_CONFIG_LOCATION_PARAM);
150    
151                    configurableWebApplicationContext.setConfigLocation(configLocation);
152    
153                    configurableWebApplicationContext.addBeanFactoryPostProcessor(
154                            new PortletBeanFactoryPostProcessor());
155            }
156    
157            @Override
158            protected Class<?> determineContextClass(ServletContext servletContext) {
159                    return PortletApplicationContext.class;
160            }
161    
162            @Override
163            protected ApplicationContext loadParentContext(
164                    ServletContext servletContext) {
165    
166                    return null;
167            }
168    
169            private static final String _PORTAL_CONFIG_LOCATION_PARAM =
170                    "portalContextConfigLocation";
171    
172            private static Log _log = LogFactoryUtil.getLog(
173                    PortletContextLoaderListener.class);
174    
175    }