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    /**
040     * @author Shuyang Zhou
041     * @author Alexander Chow
042     */
043    public class PortletSessionFactoryImpl extends SessionFactoryImpl {
044    
045            @Override
046            public void closeSession(Session session) throws ORMException {
047                    if (session != null) {
048                            session.flush();
049    
050                            if (!PropsValues.SPRING_HIBERNATE_SESSION_DELEGATED) {
051                                    session.close();
052                            }
053                    }
054            }
055    
056            @Override
057            public Session openSession() throws ORMException {
058                    SessionFactory sessionFactory = getSessionFactory();
059    
060                    org.hibernate.Session session = null;
061    
062                    if (PropsValues.SPRING_HIBERNATE_SESSION_DELEGATED) {
063                            Connection connection = CurrentConnectionUtil.getConnection(
064                                    getDataSource());
065    
066                            if (connection == null) {
067                                    session = sessionFactory.getCurrentSession();
068                            }
069                            else {
070                                    session = sessionFactory.openSession(connection);
071                            }
072                    }
073                    else {
074                            session = sessionFactory.openSession();
075                    }
076    
077                    if (_log.isDebugEnabled()) {
078                            org.hibernate.impl.SessionImpl sessionImpl =
079                                    (org.hibernate.impl.SessionImpl)session;
080    
081                            _log.debug(
082                                    "Session is using connection release mode " +
083                                            sessionImpl.getConnectionReleaseMode());
084                    }
085    
086                    return wrapSession(session);
087            }
088    
089            public void setDataSource(DataSource dataSource) {
090                    _dataSource = dataSource;
091            }
092    
093            protected SessionFactory createSessionFactory(DataSource dataSource) {
094                    String servletContextName =
095                            PortletClassLoaderUtil.getServletContextName();
096    
097                    ClassLoader classLoader = getSessionFactoryClassLoader();
098    
099                    PortletClassLoaderUtil.setServletContextName(
100                            ClassLoaderPool.getContextName(classLoader));
101    
102                    try {
103                            PortletHibernateConfiguration portletHibernateConfiguration =
104                                    new PortletHibernateConfiguration();
105    
106                            portletHibernateConfiguration.setDataSource(dataSource);
107    
108                            SessionFactory sessionFactory = null;
109    
110                            try {
111                                    sessionFactory =
112                                            portletHibernateConfiguration.buildSessionFactory();
113                            }
114                            catch (Exception e) {
115                                    _log.error(e, e);
116    
117                                    return null;
118                            }
119    
120                            return sessionFactory;
121                    }
122                    finally {
123                            PortletClassLoaderUtil.setServletContextName(servletContextName);
124                    }
125            }
126    
127            protected DataSource getDataSource() {
128                    ShardDataSourceTargetSource shardDataSourceTargetSource =
129                            (ShardDataSourceTargetSource)
130                                    InfrastructureUtil.getShardDataSourceTargetSource();
131    
132                    if (shardDataSourceTargetSource != null) {
133                            return shardDataSourceTargetSource.getDataSource();
134                    }
135                    else {
136                            return _dataSource;
137                    }
138            }
139    
140            protected SessionFactory getSessionFactory() {
141                    ShardDataSourceTargetSource shardDataSourceTargetSource =
142                            (ShardDataSourceTargetSource)
143                                    InfrastructureUtil.getShardDataSourceTargetSource();
144    
145                    if (shardDataSourceTargetSource == null) {
146                            return getSessionFactoryImplementor();
147                    }
148    
149                    DataSource dataSource = shardDataSourceTargetSource.getDataSource();
150    
151                    SessionFactory sessionFactory = getSessionFactory(dataSource);
152    
153                    if (sessionFactory != null) {
154                            return sessionFactory;
155                    }
156    
157                    sessionFactory = createSessionFactory(dataSource);
158    
159                    if (sessionFactory != null) {
160                            putSessionFactory(dataSource, sessionFactory);
161                    }
162    
163                    return sessionFactory;
164            }
165    
166            protected SessionFactory getSessionFactory(DataSource dataSource) {
167                    return _sessionFactories.get(dataSource);
168            }
169    
170            protected void putSessionFactory(
171                    DataSource dataSource, SessionFactory sessionFactory) {
172    
173                    _sessionFactories.put(dataSource, sessionFactory);
174            }
175    
176            @Override
177            protected Session wrapSession(org.hibernate.Session session) {
178                    return DoPrivilegedUtil.wrapWhenActive(super.wrapSession(session));
179            }
180    
181            private static final Log _log = LogFactoryUtil.getLog(
182                    PortletSessionFactoryImpl.class);
183    
184            private DataSource _dataSource;
185            private final Map<DataSource, SessionFactory> _sessionFactories =
186                    new HashMap<DataSource, SessionFactory>();
187    
188    }