001    /**
002     * Copyright (c) 2000-2010 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.kernel.servlet;
016    
017    import com.liferay.portal.kernel.deploy.hot.HotDeployEvent;
018    import com.liferay.portal.kernel.deploy.hot.HotDeployUtil;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.util.InfrastructureUtil;
022    import com.liferay.portal.kernel.util.PortalInitable;
023    import com.liferay.portal.kernel.util.PortalInitableUtil;
024    import com.liferay.portal.kernel.util.ServerDetector;
025    
026    import java.lang.reflect.Method;
027    
028    import javax.naming.Context;
029    import javax.naming.InitialContext;
030    import javax.naming.NamingException;
031    
032    import javax.servlet.ServletContext;
033    import javax.servlet.ServletContextEvent;
034    import javax.servlet.ServletContextListener;
035    
036    import javax.sql.DataSource;
037    
038    /**
039     * @author Ivica Cardic
040     * @author Brian Wing Shun Chan
041     */
042    public class PortletContextListener
043            implements PortalInitable, ServletContextListener {
044    
045            public void contextDestroyed(ServletContextEvent event) {
046                    ServletContext servletContext = event.getServletContext();
047    
048                    Thread currentThread = Thread.currentThread();
049    
050                    ClassLoader contextClassLoader = currentThread.getContextClassLoader();
051    
052                    HotDeployUtil.fireUndeployEvent(
053                            new HotDeployEvent(servletContext, contextClassLoader));
054    
055                    try {
056                            if (!_bindLiferayPool) {
057                                    return;
058                            }
059    
060                            _bindLiferayPool = false;
061    
062                            if (_log.isDebugEnabled()) {
063                                    _log.debug("Dynamically unbinding the Liferay data source");
064                            }
065    
066                            Context context = new InitialContext();
067    
068                            try {
069                                    context.lookup(_JNDI_JDBC_LIFERAY_POOL);
070                            }
071                            catch (NamingException ne) {
072                                    context.unbind(_JNDI_JDBC_LIFERAY_POOL);
073                            }
074    
075                            try {
076                                    context.lookup(_JNDI_JDBC);
077                            }
078                            catch (NamingException ne) {
079                                    context.destroySubcontext(_JNDI_JDBC);
080                            }
081                    }
082                    catch (Exception e) {
083                            if (_log.isWarnEnabled()) {
084                                    _log.warn(
085                                            "Unable to dynamically unbind the Liferay data source: "
086                                                    + e.getMessage());
087                            }
088                    }
089            }
090    
091            public void contextInitialized(ServletContextEvent event) {
092                    _servletContext = event.getServletContext();
093    
094                    Thread currentThread = Thread.currentThread();
095    
096                    _portletClassLoader = currentThread.getContextClassLoader();
097    
098                    PortalInitableUtil.init(this);
099            }
100    
101            public void portalInit() {
102                    HotDeployUtil.fireDeployEvent(
103                            new HotDeployEvent(_servletContext, _portletClassLoader));
104    
105                    try {
106                            if (ServerDetector.isGlassfish()) {
107                                    return;
108                            }
109    
110                            if (_log.isDebugEnabled()) {
111                                    _log.debug("Dynamically binding the Liferay data source");
112                            }
113    
114                            DataSource dataSource = InfrastructureUtil.getDataSource();
115    
116                            if (dataSource == null) {
117                                    if (_log.isDebugEnabled()) {
118                                            _log.debug(
119                                                    "Abort dynamically binding the Liferay data source " +
120                                                            "because it is not available");
121                                    }
122    
123                                    return;
124                            }
125    
126                            Context context = new InitialContext();
127    
128                            try {
129                                    context.lookup(_JNDI_JDBC);
130                            }
131                            catch (NamingException ne) {
132                                    context.createSubcontext(_JNDI_JDBC);
133                            }
134    
135                            try {
136                                    context.lookup(_JNDI_JDBC_LIFERAY_POOL);
137                            }
138                            catch (NamingException ne) {
139                                    try {
140                                            Method method = dataSource.getClass().getMethod(
141                                                    "getTargetDataSource");
142    
143                                            dataSource = (DataSource)method.invoke(dataSource);
144                                    }
145                                    catch (NoSuchMethodException nsme) {
146                                    }
147    
148                                    context.bind(_JNDI_JDBC_LIFERAY_POOL, dataSource);
149                            }
150    
151                            _bindLiferayPool = true;
152                    }
153                    catch (Exception e) {
154                            if (_log.isWarnEnabled()) {
155                                    _log.warn(
156                                            "Unable to dynamically bind the Liferay data source: "
157                                                    + e.getMessage());
158                            }
159                    }
160            }
161    
162            private static final String _JNDI_JDBC = "java_liferay:jdbc";
163    
164            private static final String _JNDI_JDBC_LIFERAY_POOL =
165                    _JNDI_JDBC + "/LiferayPool";
166    
167            private static Log _log = LogFactoryUtil.getLog(
168                    PortletContextListener.class);
169    
170            private boolean _bindLiferayPool;
171            private ClassLoader _portletClassLoader;
172            private ServletContext _servletContext;
173    
174    }