001    /**
002     * Copyright (c) 2000-present 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.dao.jdbc.util;
016    
017    import com.liferay.portal.dao.orm.hibernate.SessionFactoryImpl;
018    import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
019    import com.liferay.portal.kernel.dao.jdbc.DataSourceFactoryUtil;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.spring.hibernate.PortalHibernateConfiguration;
023    
024    import java.util.Properties;
025    
026    import javax.sql.DataSource;
027    
028    import org.hibernate.engine.SessionFactoryImplementor;
029    
030    import org.springframework.beans.factory.BeanFactory;
031    import org.springframework.beans.factory.BeanFactoryAware;
032    import org.springframework.orm.hibernate3.HibernateTransactionManager;
033    import org.springframework.transaction.support.AbstractPlatformTransactionManager;
034    
035    /**
036     * @author Shuyang Zhou
037     */
038    public class DataSourceSwapper implements BeanFactoryAware {
039    
040            public static void swapCounterDataSource(Properties properties)
041                    throws Exception {
042    
043                    if (_log.isInfoEnabled()) {
044                            _log.info("Create new counter data source");
045                    }
046    
047                    DataSource newDataSource = DataSourceFactoryUtil.initDataSource(
048                            properties);
049    
050                    DataSource oldDataSource =
051                            _counterDataSourceWrapper.getWrappedDataSource();
052    
053                    if (_log.isInfoEnabled()) {
054                            _log.info("Set new counter data source");
055                    }
056    
057                    _counterDataSourceWrapper.setWrappedDataSource(newDataSource);
058    
059                    if (_log.isInfoEnabled()) {
060                            _log.info("Destroy old counter data source");
061                    }
062    
063                    DataSourceFactoryUtil.destroyDataSource(oldDataSource);
064    
065                    if (_log.isInfoEnabled()) {
066                            _log.info("Reinitialize Hibernate for new counter data source");
067                    }
068    
069                    _reinitializeHibernate("counterSessionFactory", newDataSource);
070            }
071    
072            public static void swapLiferayDataSource(Properties properties)
073                    throws Exception {
074    
075                    if (_log.isInfoEnabled()) {
076                            _log.info("Create new liferay data source");
077                    }
078    
079                    DataSource newDataSource = DataSourceFactoryUtil.initDataSource(
080                            properties);
081    
082                    DataSource oldDataSource =
083                            _liferayDataSourceWrapper.getWrappedDataSource();
084    
085                    if (_log.isInfoEnabled()) {
086                            _log.info("Set new liferay data source");
087                    }
088    
089                    _liferayDataSourceWrapper.setWrappedDataSource(newDataSource);
090    
091                    if (_log.isInfoEnabled()) {
092                            _log.info("Destroy old liferay data source");
093                    }
094    
095                    DataSourceFactoryUtil.destroyDataSource(oldDataSource);
096    
097                    if (_log.isInfoEnabled()) {
098                            _log.info("Reinitialize Hibernate for new liferay data source");
099                    }
100    
101                    _reinitializeHibernate("liferaySessionFactory", newDataSource);
102            }
103    
104            @Override
105            public void setBeanFactory(BeanFactory beanFactory) {
106                    _beanFactory = beanFactory;
107            }
108    
109            public void setCounterDataSourceWrapper(
110                    DataSourceWrapper counterDataSourceWrapper) {
111    
112                    _counterDataSourceWrapper = counterDataSourceWrapper;
113            }
114    
115            public void setLiferayDataSourceWrapper(
116                    DataSourceWrapper liferayDataSourceWrapper) {
117    
118                    _liferayDataSourceWrapper = liferayDataSourceWrapper;
119            }
120    
121            private static void _reinitializeHibernate(
122                            String name, DataSource dataSource)
123                    throws Exception {
124    
125                    PortalHibernateConfiguration portalHibernateConfiguration =
126                            new PortalHibernateConfiguration();
127    
128                    portalHibernateConfiguration.setBeanFactory(_beanFactory);
129                    portalHibernateConfiguration.setDataSource(dataSource);
130    
131                    portalHibernateConfiguration.afterPropertiesSet();
132    
133                    SessionFactoryImplementor sessionFactoryImplementor =
134                            (SessionFactoryImplementor)portalHibernateConfiguration.getObject();
135    
136                    SessionFactoryImpl sessionFactoryImpl =
137                            (SessionFactoryImpl)PortalBeanLocatorUtil.locate(name);
138    
139                    sessionFactoryImpl.setSessionFactoryImplementor(
140                            sessionFactoryImplementor);
141    
142                    AbstractPlatformTransactionManager abstractPlatformTransactionManager =
143                            (AbstractPlatformTransactionManager)PortalBeanLocatorUtil.locate(
144                                    "liferayTransactionManager");
145    
146                    if (abstractPlatformTransactionManager instanceof
147                                    HibernateTransactionManager) {
148    
149                            HibernateTransactionManager hibernateTransactionManager =
150                                    (HibernateTransactionManager)abstractPlatformTransactionManager;
151    
152                            hibernateTransactionManager.setSessionFactory(
153                                    sessionFactoryImplementor);
154                    }
155                    else if (_log.isWarnEnabled()) {
156                            _log.warn(
157                                    "Unable to swap to session factory for " +
158                                            abstractPlatformTransactionManager.getClass() +
159                                                    " which may cause subsequent transaction failures");
160                    }
161            }
162    
163            private static final Log _log = LogFactoryUtil.getLog(
164                    DataSourceSwapper.class);
165    
166            private static BeanFactory _beanFactory;
167            private static DataSourceWrapper _counterDataSourceWrapper;
168            private static DataSourceWrapper _liferayDataSourceWrapper;
169    
170    }