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