001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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    import org.springframework.beans.BeansException;
039    import org.springframework.beans.factory.BeanFactory;
040    import org.springframework.beans.factory.BeanFactoryAware;
041    
042    /**
043     * @author Shuyang Zhou
044     * @author Alexander Chow
045     */
046    public class PortletSessionFactoryImpl
047            extends SessionFactoryImpl implements BeanFactoryAware {
048    
049            public void afterPropertiesSet() {
050                    if (_dataSource == InfrastructureUtil.getDataSource()) {
051    
052                            // Register only if the current session factory is using the portal
053                            // data source
054    
055                            portletSessionFactories.add(this);
056                    }
057            }
058    
059            @Override
060            public void closeSession(Session session) throws ORMException {
061                    if (session != null) {
062                            session.flush();
063    
064                            if (!PropsValues.SPRING_HIBERNATE_SESSION_DELEGATED) {
065                                    session.close();
066                            }
067                    }
068            }
069    
070            @Override
071            public void destroy() {
072                    portletSessionFactories.remove(this);
073            }
074    
075            public BeanFactory getBeanFactory() {
076                    return _beanFactory;
077            }
078    
079            public DataSource getDataSource() {
080                    ShardDataSourceTargetSource shardDataSourceTargetSource =
081                            (ShardDataSourceTargetSource)
082                                    InfrastructureUtil.getShardDataSourceTargetSource();
083    
084                    if (shardDataSourceTargetSource != null) {
085                            return shardDataSourceTargetSource.getDataSource();
086                    }
087                    else {
088                            return _dataSource;
089                    }
090            }
091    
092            @Override
093            public Session openSession() throws ORMException {
094                    SessionFactory sessionFactory = getSessionFactory();
095    
096                    org.hibernate.Session session = null;
097    
098                    if (PropsValues.SPRING_HIBERNATE_SESSION_DELEGATED) {
099                            Connection connection = CurrentConnectionUtil.getConnection(
100                                    getDataSource());
101    
102                            if (connection == null) {
103                                    session = sessionFactory.getCurrentSession();
104                            }
105                            else {
106                                    session = sessionFactory.openSession(connection);
107                            }
108                    }
109                    else {
110                            session = sessionFactory.openSession();
111                    }
112    
113                    if (_log.isDebugEnabled()) {
114                            org.hibernate.impl.SessionImpl sessionImpl =
115                                    (org.hibernate.impl.SessionImpl)session;
116    
117                            _log.debug(
118                                    "Session is using connection release mode " +
119                                            sessionImpl.getConnectionReleaseMode());
120                    }
121    
122                    return wrapSession(session);
123            }
124    
125            @Override
126            public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
127                    _beanFactory = beanFactory;
128            }
129    
130            public void setDataSource(DataSource dataSource) {
131                    _dataSource = dataSource;
132            }
133    
134            protected SessionFactory getSessionFactory() {
135                    ShardDataSourceTargetSource shardDataSourceTargetSource =
136                            (ShardDataSourceTargetSource)
137                                    InfrastructureUtil.getShardDataSourceTargetSource();
138    
139                    if (shardDataSourceTargetSource == null) {
140                            return getSessionFactoryImplementor();
141                    }
142    
143                    DataSource dataSource = shardDataSourceTargetSource.getDataSource();
144    
145                    SessionFactory sessionFactory = _sessionFactories.get(dataSource);
146    
147                    if (sessionFactory != null) {
148                            return sessionFactory;
149                    }
150    
151                    ClassLoader classLoader = PortletClassLoaderUtil.getClassLoader();
152    
153                    try {
154                            PortletClassLoaderUtil.setClassLoader(
155                                    getSessionFactoryClassLoader());
156    
157                            PortletHibernateConfiguration portletHibernateConfiguration =
158                                    new PortletHibernateConfiguration();
159    
160                            portletHibernateConfiguration.setBeanFactory(_beanFactory);
161                            portletHibernateConfiguration.setDataSource(dataSource);
162    
163                            try {
164                                    sessionFactory =
165                                            portletHibernateConfiguration.buildSessionFactory();
166                            }
167                            catch (Exception e) {
168                                    _log.error(e, e);
169    
170                                    return null;
171                            }
172    
173                            _sessionFactories.put(dataSource, sessionFactory);
174    
175                            return sessionFactory;
176                    }
177                    finally {
178                            PortletClassLoaderUtil.setClassLoader(classLoader);
179                    }
180            }
181    
182            @Override
183            protected Session wrapSession(org.hibernate.Session session) {
184                    return DoPrivilegedUtil.wrapWhenActive(super.wrapSession(session));
185            }
186    
187            private static Log _log = LogFactoryUtil.getLog(
188                    PortletSessionFactoryImpl.class);
189    
190            private BeanFactory _beanFactory;
191            private DataSource _dataSource;
192            private Map<DataSource, SessionFactory> _sessionFactories =
193                    new HashMap<DataSource, SessionFactory>();
194    
195    }