001    /**
002     * Copyright (c) 2000-2013 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.InfrastructureUtil;
025    import com.liferay.portal.security.lang.DoPrivilegedUtil;
026    import com.liferay.portal.spring.hibernate.PortletHibernateConfiguration;
027    import com.liferay.portal.util.PropsValues;
028    
029    import java.sql.Connection;
030    
031    import java.util.HashMap;
032    import java.util.Map;
033    
034    import javax.sql.DataSource;
035    
036    import org.hibernate.SessionFactory;
037    
038    /**
039     * @author Shuyang Zhou
040     * @author Alexander Chow
041     */
042    public class PortletSessionFactoryImpl extends SessionFactoryImpl {
043    
044            public void afterPropertiesSet() {
045                    if (_dataSource == InfrastructureUtil.getDataSource()) {
046    
047                            // Register only if the current session factory is using the portal
048                            // data source
049    
050                            portletSessionFactories.add(this);
051                    }
052            }
053    
054            @Override
055            public void closeSession(Session session) throws ORMException {
056                    if (session != null) {
057                            session.flush();
058    
059                            if (!PropsValues.SPRING_HIBERNATE_SESSION_DELEGATED) {
060                                    session.close();
061                            }
062                    }
063            }
064    
065            @Override
066            public void destroy() {
067                    portletSessionFactories.remove(this);
068            }
069    
070            public DataSource getDataSource() {
071                    ShardDataSourceTargetSource shardDataSourceTargetSource =
072                            (ShardDataSourceTargetSource)
073                                    InfrastructureUtil.getShardDataSourceTargetSource();
074    
075                    if (shardDataSourceTargetSource != null) {
076                            return shardDataSourceTargetSource.getDataSource();
077                    }
078                    else {
079                            return _dataSource;
080                    }
081            }
082    
083            @Override
084            public Session openSession() throws ORMException {
085                    SessionFactory sessionFactory = getSessionFactory();
086    
087                    org.hibernate.Session session = null;
088    
089                    if (PropsValues.SPRING_HIBERNATE_SESSION_DELEGATED) {
090                            Connection connection = CurrentConnectionUtil.getConnection(
091                                    getDataSource());
092    
093                            if (connection == null) {
094                                    session = sessionFactory.getCurrentSession();
095                            }
096                            else {
097                                    session = sessionFactory.openSession(connection);
098                            }
099                    }
100                    else {
101                            session = sessionFactory.openSession();
102                    }
103    
104                    if (_log.isDebugEnabled()) {
105                            org.hibernate.impl.SessionImpl sessionImpl =
106                                    (org.hibernate.impl.SessionImpl)session;
107    
108                            _log.debug(
109                                    "Session is using connection release mode " +
110                                            sessionImpl.getConnectionReleaseMode());
111                    }
112    
113                    return wrapSession(session);
114            }
115    
116            public void setDataSource(DataSource dataSource) {
117                    _dataSource = dataSource;
118            }
119    
120            protected SessionFactory getSessionFactory() {
121                    ShardDataSourceTargetSource shardDataSourceTargetSource =
122                            (ShardDataSourceTargetSource)
123                                    InfrastructureUtil.getShardDataSourceTargetSource();
124    
125                    if (shardDataSourceTargetSource == null) {
126                            return getSessionFactoryImplementor();
127                    }
128    
129                    DataSource dataSource = shardDataSourceTargetSource.getDataSource();
130    
131                    SessionFactory sessionFactory = _sessionFactories.get(dataSource);
132    
133                    if (sessionFactory != null) {
134                            return sessionFactory;
135                    }
136    
137                    ClassLoader classLoader = PortletClassLoaderUtil.getClassLoader();
138    
139                    try {
140                            PortletClassLoaderUtil.setClassLoader(
141                                    getSessionFactoryClassLoader());
142    
143                            PortletHibernateConfiguration portletHibernateConfiguration =
144                                    new PortletHibernateConfiguration();
145    
146                            portletHibernateConfiguration.setDataSource(dataSource);
147    
148                            try {
149                                    sessionFactory =
150                                            portletHibernateConfiguration.buildSessionFactory();
151                            }
152                            catch (Exception e) {
153                                    _log.error(e, e);
154    
155                                    return null;
156                            }
157    
158                            _sessionFactories.put(dataSource, sessionFactory);
159    
160                            return sessionFactory;
161                    }
162                    finally {
163                            PortletClassLoaderUtil.setClassLoader(classLoader);
164                    }
165            }
166    
167            @Override
168            protected Session wrapSession(org.hibernate.Session session) {
169                    return DoPrivilegedUtil.wrapWhenActive(super.wrapSession(session));
170            }
171    
172            private static Log _log = LogFactoryUtil.getLog(
173                    PortletSessionFactoryImpl.class);
174    
175            private DataSource _dataSource;
176            private Map<DataSource, SessionFactory> _sessionFactories =
177                    new HashMap<DataSource, SessionFactory>();
178    
179    }