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.orm.hibernate;
016    
017    import com.liferay.portal.dao.shard.ShardDataSourceTargetSource;
018    import com.liferay.portal.kernel.dao.jdbc.CurrentConnectionUtil;
019    import com.liferay.portal.kernel.dao.orm.ORMException;
020    import com.liferay.portal.kernel.dao.orm.Session;
021    import com.liferay.portal.kernel.log.Log;
022    import com.liferay.portal.kernel.log.LogFactoryUtil;
023    import com.liferay.portal.kernel.portlet.PortletClassLoaderUtil;
024    import com.liferay.portal.kernel.util.ClassLoaderPool;
025    import com.liferay.portal.kernel.util.InfrastructureUtil;
026    import com.liferay.portal.security.lang.DoPrivilegedUtil;
027    import com.liferay.portal.spring.hibernate.PortletHibernateConfiguration;
028    import com.liferay.portal.util.PropsValues;
029    
030    import java.sql.Connection;
031    
032    import java.util.HashMap;
033    import java.util.Map;
034    
035    import javax.sql.DataSource;
036    
037    import org.hibernate.SessionFactory;
038    
039    import org.springframework.beans.BeansException;
040    import org.springframework.beans.factory.BeanFactory;
041    import org.springframework.beans.factory.BeanFactoryAware;
042    
043    /**
044     * @author Shuyang Zhou
045     * @author Alexander Chow
046     */
047    public class PortletSessionFactoryImpl
048            extends SessionFactoryImpl implements BeanFactoryAware {
049    
050            @Override
051            public void closeSession(Session session) throws ORMException {
052                    if (session != null) {
053                            session.flush();
054    
055                            if (!PropsValues.SPRING_HIBERNATE_SESSION_DELEGATED) {
056                                    session.close();
057                            }
058                    }
059            }
060    
061            @Override
062            public Session openSession() throws ORMException {
063                    SessionFactory sessionFactory = getSessionFactory();
064    
065                    org.hibernate.Session session = null;
066    
067                    if (PropsValues.SPRING_HIBERNATE_SESSION_DELEGATED) {
068                            Connection connection = CurrentConnectionUtil.getConnection(
069                                    getDataSource());
070    
071                            if (connection == null) {
072                                    session = sessionFactory.getCurrentSession();
073                            }
074                            else {
075                                    session = sessionFactory.openSession(connection);
076                            }
077                    }
078                    else {
079                            session = sessionFactory.openSession();
080                    }
081    
082                    if (_log.isDebugEnabled()) {
083                            org.hibernate.impl.SessionImpl sessionImpl =
084                                    (org.hibernate.impl.SessionImpl)session;
085    
086                            _log.debug(
087                                    "Session is using connection release mode " +
088                                            sessionImpl.getConnectionReleaseMode());
089                    }
090    
091                    return wrapSession(session);
092            }
093    
094            @Override
095            public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
096                    _beanFactory = beanFactory;
097            }
098    
099            public void setDataSource(DataSource dataSource) {
100                    _dataSource = dataSource;
101            }
102    
103            protected SessionFactory createSessionFactory(DataSource dataSource) {
104                    String servletContextName =
105                            PortletClassLoaderUtil.getServletContextName();
106    
107                    ClassLoader classLoader = getSessionFactoryClassLoader();
108    
109                    PortletClassLoaderUtil.setServletContextName(
110                            ClassLoaderPool.getContextName(classLoader));
111    
112                    try {
113                            PortletHibernateConfiguration portletHibernateConfiguration =
114                                    new PortletHibernateConfiguration();
115    
116                            portletHibernateConfiguration.setBeanFactory(_beanFactory);
117                            portletHibernateConfiguration.setDataSource(dataSource);
118    
119                            SessionFactory sessionFactory = null;
120    
121                            try {
122                                    sessionFactory =
123                                            portletHibernateConfiguration.buildSessionFactory();
124                            }
125                            catch (Exception e) {
126                                    _log.error(e, e);
127    
128                                    return null;
129                            }
130    
131                            return sessionFactory;
132                    }
133                    finally {
134                            PortletClassLoaderUtil.setServletContextName(servletContextName);
135                    }
136            }
137    
138            protected BeanFactory getBeanFactory() {
139                    return _beanFactory;
140            }
141    
142            protected DataSource getDataSource() {
143                    ShardDataSourceTargetSource shardDataSourceTargetSource =
144                            (ShardDataSourceTargetSource)
145                                    InfrastructureUtil.getShardDataSourceTargetSource();
146    
147                    if (shardDataSourceTargetSource != null) {
148                            return shardDataSourceTargetSource.getDataSource();
149                    }
150                    else {
151                            return _dataSource;
152                    }
153            }
154    
155            protected SessionFactory getSessionFactory() {
156                    ShardDataSourceTargetSource shardDataSourceTargetSource =
157                            (ShardDataSourceTargetSource)
158                                    InfrastructureUtil.getShardDataSourceTargetSource();
159    
160                    if (shardDataSourceTargetSource == null) {
161                            return getSessionFactoryImplementor();
162                    }
163    
164                    DataSource dataSource = shardDataSourceTargetSource.getDataSource();
165    
166                    SessionFactory sessionFactory = getSessionFactory(dataSource);
167    
168                    if (sessionFactory != null) {
169                            return sessionFactory;
170                    }
171    
172                    sessionFactory = createSessionFactory(dataSource);
173    
174                    if (sessionFactory != null) {
175                            putSessionFactory(dataSource, sessionFactory);
176                    }
177    
178                    return sessionFactory;
179            }
180    
181            protected SessionFactory getSessionFactory(DataSource dataSource) {
182                    return _sessionFactories.get(dataSource);
183            }
184    
185            protected void putSessionFactory(
186                    DataSource dataSource, SessionFactory sessionFactory) {
187    
188                    _sessionFactories.put(dataSource, sessionFactory);
189            }
190    
191            @Override
192            protected Session wrapSession(org.hibernate.Session session) {
193                    return DoPrivilegedUtil.wrapWhenActive(super.wrapSession(session));
194            }
195    
196            private static final Log _log = LogFactoryUtil.getLog(
197                    PortletSessionFactoryImpl.class);
198    
199            private BeanFactory _beanFactory;
200            private DataSource _dataSource;
201            private final Map<DataSource, SessionFactory> _sessionFactories =
202                    new HashMap<DataSource, SessionFactory>();
203    
204    }