001    /**
002     * Copyright (c) 2000-2012 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.spring.hibernate;
016    
017    import com.liferay.portal.kernel.dao.db.DB;
018    import com.liferay.portal.kernel.dao.db.DBFactoryUtil;
019    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.util.Converter;
023    import com.liferay.portal.kernel.util.PropsKeys;
024    import com.liferay.portal.kernel.util.StringUtil;
025    import com.liferay.portal.kernel.util.Validator;
026    import com.liferay.portal.security.pacl.PACLClassLoaderUtil;
027    import com.liferay.portal.util.PropsUtil;
028    import com.liferay.portal.util.PropsValues;
029    
030    import java.io.InputStream;
031    
032    import java.net.URL;
033    
034    import java.util.Enumeration;
035    import java.util.Map;
036    import java.util.Properties;
037    
038    import javassist.util.proxy.ProxyFactory;
039    
040    import org.hibernate.HibernateException;
041    import org.hibernate.SessionFactory;
042    import org.hibernate.cfg.Configuration;
043    import org.hibernate.cfg.Environment;
044    import org.hibernate.dialect.Dialect;
045    
046    import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
047    
048    /**
049     * @author Brian Wing Shun Chan
050     * @author Marcellus Tavares
051     * @author Shuyang Zhou
052     * @author Tomas Polesovsky
053     */
054    public class PortalHibernateConfiguration extends LocalSessionFactoryBean {
055    
056            @Override
057            public SessionFactory buildSessionFactory() throws Exception {
058                    ProxyFactory.classLoaderProvider =
059                            new ProxyFactory.ClassLoaderProvider() {
060    
061                                    public ClassLoader get(ProxyFactory proxyFactory) {
062                                            return PACLClassLoaderUtil.getContextClassLoader();
063                                    }
064    
065                            };
066    
067                    setBeanClassLoader(getConfigurationClassLoader());
068    
069                    return super.buildSessionFactory();
070            }
071    
072            @Override
073            public void destroy() throws HibernateException {
074                    setBeanClassLoader(null);
075    
076                    super.destroy();
077            }
078    
079            public void setHibernateConfigurationConverter(
080                    Converter<String> hibernateConfigurationConverter) {
081    
082                    _hibernateConfigurationConverter = hibernateConfigurationConverter;
083            }
084    
085            protected Dialect determineDialect() {
086                    return DialectDetector.getDialect(getDataSource());
087            }
088    
089            protected ClassLoader getConfigurationClassLoader() {
090                    Class<?> clazz = getClass();
091    
092                    return clazz.getClassLoader();
093            }
094    
095            protected String[] getConfigurationResources() {
096                    return PropsUtil.getArray(PropsKeys.HIBERNATE_CONFIGS);
097            }
098    
099            @Override
100            protected Configuration newConfiguration() {
101                    Configuration configuration = new Configuration();
102    
103                    try {
104                            String[] resources = getConfigurationResources();
105    
106                            for (String resource : resources) {
107                                    try {
108                                            readResource(configuration, resource);
109                                    }
110                                    catch (Exception e2) {
111                                            if (_log.isWarnEnabled()) {
112                                                    _log.warn(e2, e2);
113                                            }
114                                    }
115                            }
116    
117                            configuration.setProperties(PropsUtil.getProperties());
118    
119                            if (Validator.isNull(PropsValues.HIBERNATE_DIALECT)) {
120                                    Dialect dialect = determineDialect();
121    
122                                    setDB(dialect);
123    
124                                    Class<?> clazz = dialect.getClass();
125    
126                                    configuration.setProperty("hibernate.dialect", clazz.getName());
127                            }
128    
129                            DB db = DBFactoryUtil.getDB();
130    
131                            String dbType = db.getType();
132    
133                            if (dbType.equals(DB.TYPE_HYPERSONIC)) {
134                                    //configuration.setProperty("hibernate.jdbc.batch_size", "0");
135                            }
136                    }
137                    catch (Exception e1) {
138                            _log.error(e1, e1);
139                    }
140    
141                    Properties hibernateProperties = getHibernateProperties();
142    
143                    if (hibernateProperties != null) {
144                            for (Map.Entry<Object, Object> entry :
145                                            hibernateProperties.entrySet()) {
146    
147                                    String key = (String)entry.getKey();
148                                    String value = (String)entry.getValue();
149    
150                                    configuration.setProperty(key, value);
151                            }
152                    }
153    
154                    return configuration;
155            }
156    
157            @Override
158            protected void postProcessConfiguration(Configuration configuration) {
159    
160                    // Make sure that the Hibernate settings from PropsUtil are set. See the
161                    // buildSessionFactory implementation in the LocalSessionFactoryBean
162                    // class to understand how Spring automates a lot of configuration for
163                    // Hibernate.
164    
165                    String connectionReleaseMode = PropsUtil.get(
166                            Environment.RELEASE_CONNECTIONS);
167    
168                    if (Validator.isNotNull(connectionReleaseMode)) {
169                            configuration.setProperty(
170                                    Environment.RELEASE_CONNECTIONS, connectionReleaseMode);
171                    }
172            }
173    
174            protected void readResource(
175                            Configuration configuration, InputStream inputStream)
176                    throws Exception {
177    
178                    if (inputStream == null) {
179                            return;
180                    }
181    
182                    if (_hibernateConfigurationConverter != null) {
183                            String configurationString = StringUtil.read(inputStream);
184    
185                            inputStream.close();
186    
187                            configurationString = _hibernateConfigurationConverter.convert(
188                                    configurationString);
189    
190                            inputStream = new UnsyncByteArrayInputStream(
191                                    configurationString.getBytes());
192                    }
193    
194                    configuration = configuration.addInputStream(inputStream);
195    
196                    inputStream.close();
197            }
198    
199            protected void readResource(Configuration configuration, String resource)
200                    throws Exception {
201    
202                    ClassLoader classLoader = getConfigurationClassLoader();
203    
204                    if (resource.startsWith("classpath*:")) {
205                            String name = resource.substring("classpath*:".length());
206    
207                            Enumeration<URL> enu = classLoader.getResources(name);
208    
209                            if (_log.isDebugEnabled() && !enu.hasMoreElements()) {
210                                    _log.debug("No resources found for " + name);
211                            }
212    
213                            while (enu.hasMoreElements()) {
214                                    URL url = enu.nextElement();
215    
216                                    InputStream inputStream = url.openStream();
217    
218                                    readResource(configuration, inputStream);
219                            }
220                    }
221                    else {
222                            InputStream inputStream = classLoader.getResourceAsStream(resource);
223    
224                            readResource(configuration, inputStream);
225                    }
226            }
227    
228            protected void setDB(Dialect dialect) {
229                    DBFactoryUtil.setDB(dialect);
230            }
231    
232            private static Log _log = LogFactoryUtil.getLog(
233                    PortalHibernateConfiguration.class);
234    
235            private Converter<String> _hibernateConfigurationConverter;
236    
237    }