/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is vox-mail.
*
* The Initial Developer of the Original Code is Voxeo Corporation.
* Portions created by Voxeo are Copyright (C) 2000-2007.
* All rights reserved.
*
* Contributor(s):
* ICOA Inc. <info@icoa.com> (http://icoa.com)
*/
package org.voxmail.dao;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.Properties;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.MappingException;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.Transaction;
import net.sf.hibernate.cfg.Configuration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.voxmail.Voxmail;
import org.voxmail.VoxmailException;
import org.voxmail.model.Mailbox;
/**
* @author shawn
* Follows open Session in View Pattern http://www.hibernate.org/43.html
*/
public class VoxmailSessionManagement {
private static Log log = LogFactory.getLog(VoxmailSessionManagement.class);
private static SessionFactory sessions = null;
private static ThreadLocal session = new ThreadLocal();
private static ThreadLocal transaction = new ThreadLocal();
private static ThreadLocal serviceCache = new ThreadLocal();
synchronized private static SessionFactory getSessionFactory() throws VoxmailException {
if (sessions == null) {
try {
Configuration ds = new Configuration()
.addClass(Mailbox.class);
Properties props = Voxmail.getProps();
if (props.getProperty("hibernate.connection.driver_class").equalsIgnoreCase("org.hsqldb.jdbcDriver") &&
props.getProperty("hibernate.connection.url") == null)
{
String dbServer = "jdbc:hsqldb:file:"+Voxmail.getInstance().getBasePath()+"WEB-INF/db/voxmail.hsql";
dbServer = dbServer.replaceAll("/","\\\\");
props.setProperty("hibernate.connection.url",dbServer);
}
ds.setProperties(props);
sessions = ds.buildSessionFactory();
} catch (MappingException e) {
log.fatal(e);
throw new VoxmailException("getSessionFactory() failed",e);
} catch (HibernateException e) {
log.fatal(e);
throw new VoxmailException("getSessionFactory() failed",e);
}
}
return sessions;
}
public VoxmailSessionManagement() {
}
public void init() throws VoxmailException {
getSessionFactory();
}
public void destroy() throws VoxmailException {
session = null;
transaction = null;
serviceCache = null;
log = null;
sessions = null;
}
Session getSession() throws VoxmailException {
Session s;
try {
s = (Session) session.get();
if (s == null) {
s = getSessionFactory().openSession();
session.set(s);
}
getTransaction(); // create a new transaction for this session
} catch (HibernateException e) {
throw new VoxmailException("Unable to open a hibernate session.", e);
}
if (s == null) {
throw new VoxmailException("Unable to get hibernate session!");
}
return s;
}
Session getExternalSession(Connection c) throws VoxmailException {
Session s = getSessionFactory().openSession(c);
if (s == null) {
throw new VoxmailException("Unable to get hibernate session!");
}
return s;
}
Transaction getTransaction() throws VoxmailException {
Transaction t = (Transaction) transaction.get();
try {
t = (Transaction) transaction.get();
if (t == null) {
t = ((Session) session.get()).beginTransaction();
transaction.set(t);
}
} catch (HibernateException e) {
e.printStackTrace();
throw new VoxmailException("Unable to open a hibernate session.", e);
}
if (t == null) {
throw new VoxmailException("Unable to get hibernate transaction!");
}
return t;
}
public Hashtable getServiceCache() throws VoxmailException {
Hashtable h = (Hashtable) serviceCache.get();
if (h == null) {
h = new Hashtable();
serviceCache.set(h);
}
return h;
}
public void update() throws VoxmailException {
try {
getSession().flush();
} catch (HibernateException e) {
throw new VoxmailException("unable to save all the unsaved changes", e);
}
}
public void saveObject(Object object) throws VoxmailException {
try {
getSession().save(object);
} catch (HibernateException e) {
throw new VoxmailException("unable to save object", e);
}
}
public void commit() throws VoxmailException {
try {
if (isTransactionActive()) {
getTransaction().commit();
transaction.set(null);
} else if (isSessionActive()) {
getSession().connection().commit();
}
} catch (HibernateException e) {
throw new VoxmailException("Commit failed.", e);
} catch (SQLException e) {
log.error(e);
throw new VoxmailException("Commit failed.", e);
}
}
public void rollback() throws VoxmailException {
try {
if (isTransactionActive()) {
getTransaction().rollback();
transaction.set(null);
} else if (isSessionActive()) {
getSession().connection().rollback();
}
} catch (HibernateException e) {
transaction.set(null);
session.set(null);
throw new VoxmailException("Rollback failed.", e);
} catch (SQLException e) {
log.error(e);
throw new VoxmailException("Rollback failed.", e);
}
}
public void releaseSession() throws VoxmailException {
try {
if (isTransactionActive()) {
getTransaction().commit();
transaction.set(null);
}
if (isSessionActive()) {
((Session) session.get()).close();
session.set(null);
}
if (isServiceCacheActive()) {
serviceCache.set(null);
}
} catch (HibernateException e) {
transaction.set(null);
session.set(null);
log.error(e);
throw new VoxmailException("Closing Session failed.", e);
}
}
private boolean isSessionActive() {
return (session.get() != null);
}
private boolean isTransactionActive() {
return (transaction.get() != null);
}
private boolean isServiceCacheActive() {
return (serviceCache.get() != null);
}
}