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.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                                    context.unbind(_JNDI_JDBC_LIFERAY_POOL);
079                            }
080                            catch (NamingException ne) {
081                            }
082    
083                            try {
084                                    context.lookup(_JNDI_JDBC);
085                                    context.destroySubcontext(_JNDI_JDBC);
086                            }
087                            catch (NamingException ne) {
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() throws Exception {
101                    HotDeployUtil.fireDeployEvent(
102                            new HotDeployEvent(_servletContext, _portletClassLoader));
103    
104                    if (ServerDetector.isGlassfish() || ServerDetector.isJOnAS()) {
105                            return;
106                    }
107    
108                    if (_log.isDebugEnabled()) {
109                            _log.debug("Dynamically binding the Liferay data source");
110                    }
111    
112                    DataSource dataSource = InfrastructureUtil.getDataSource();
113    
114                    if (dataSource == null) {
115                            if (_log.isDebugEnabled()) {
116                                    _log.debug(
117                                            "Abort dynamically binding the Liferay data source " +
118                                                    "because it is not available");
119                            }
120    
121                            return;
122                    }
123    
124                    Context context = new InitialContext();
125    
126                    try {
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                                            Class<?> clazz = dataSource.getClass();
140    
141                                            Method method = clazz.getMethod("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    }