restoring head
[mir.git] / source / org / codecoop / mir / core / dao / hibernate / HibernateSessionManager.java
diff --git a/source/org/codecoop/mir/core/dao/hibernate/HibernateSessionManager.java b/source/org/codecoop/mir/core/dao/hibernate/HibernateSessionManager.java
new file mode 100755 (executable)
index 0000000..1eb051c
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * $Id: HibernateSessionManager.java,v 1.1 2004/11/06 16:20:48 idfx Exp $
+ * 
+ * Copyright (C) 2001, 2002, 2003, 2004 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package org.codecoop.mir.core.dao.hibernate;
+
+import net.sf.hibernate.HibernateException;
+import net.sf.hibernate.Interceptor;
+import net.sf.hibernate.Session;
+import net.sf.hibernate.SessionFactory;
+import net.sf.hibernate.cfg.Configuration;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codecoop.mir.core.dao.DatabaseFailure;
+
+/**
+ * HibernateUtil
+ * 
+ * @author idefix
+ * @version $Revision: 1.1 $
+ */
+class HibernateSessionManager {
+
+  private static Log log = LogFactory.getLog(HibernateSessionManager.class);
+
+  private static Configuration configuration;
+  private static SessionFactory sessionFactory;
+  private static final ThreadLocal threadSession = new ThreadLocal();
+  private static final ThreadLocal threadInterceptor = new ThreadLocal();
+
+  // Create the initial SessionFactory from the default configuration files
+  static {
+    try {
+      configuration = new Configuration();
+      sessionFactory = configuration.configure().buildSessionFactory();
+      log.debug("SessionFactory built.");
+    } catch (Throwable ex) {
+      log.error("Building SessionFactory failed.", ex);
+      throw new ExceptionInInitializerError(ex);
+    }
+  }
+
+  /**
+   * Returns the SessionFactory used for this static class.
+   * 
+   * @return SessionFactory
+   */
+  static SessionFactory getSessionFactory() {
+    return sessionFactory;
+  }
+
+  /**
+   * Returns the original Hibernate configuration.
+   * 
+   * @return Configuration
+   */
+  static Configuration getConfiguration() {
+    return configuration;
+  }
+
+  /**
+   * Rebuild the SessionFactory with the static Configuration.
+   *  
+   */
+  static void rebuildSessionFactory() throws DatabaseFailure {
+    synchronized (sessionFactory) {
+      try {
+        sessionFactory = getConfiguration().buildSessionFactory();
+      } catch (Exception ex) {
+        throw new DatabaseFailure(ex);
+      }
+    }
+  }
+
+  /**
+   * Rebuild the SessionFactory with the given Hibernate Configuration.
+   * 
+   * @param cfg
+   */
+  static void rebuildSessionFactory(Configuration cfg) throws DatabaseFailure {
+    synchronized (sessionFactory) {
+      try {
+        sessionFactory = cfg.buildSessionFactory();
+        configuration = cfg;
+      } catch (Exception ex) {
+        throw new DatabaseFailure(ex);
+      }
+    }
+  }
+
+  /**
+   * Retrieves the current Session local to the thread. <p/>If no Session is
+   * open, opens a new Session for the running thread.
+   * 
+   * @return Session
+   */
+  static Session getSession() throws DatabaseFailure {
+    Session s = (Session) threadSession.get();
+    try {
+      if (s == null) {
+        log.debug("Opening new Session for this thread.");
+        if (getInterceptor() != null) {
+          log.debug("Using interceptor: " + getInterceptor().getClass());
+          s = getSessionFactory().openSession(getInterceptor());
+        } else {
+          s = getSessionFactory().openSession();
+        }
+        threadSession.set(s);
+      }
+    } catch (HibernateException ex) {
+      throw new DatabaseFailure(ex);
+    }
+    return s;
+  }
+
+  /**
+   * Closes the Session local to the thread.
+   */
+  static void closeSession() throws DatabaseFailure {
+    try {
+      Session s = (Session) threadSession.get();
+      threadSession.set(null);
+      if (s != null && s.isOpen()) {
+        log.debug("Closing Session of this thread.");
+        s.close();
+      }
+    } catch (HibernateException ex) {
+      throw new DatabaseFailure(ex);
+    }
+  }
+
+  /**
+   * Reconnects a Hibernate Session to the current Thread.
+   * 
+   * @param session
+   *          The Hibernate Session to be reconnected.
+   */
+  static void reconnect(Session session) throws DatabaseFailure {
+    try {
+      session.reconnect();
+      threadSession.set(session);
+    } catch (HibernateException ex) {
+      throw new DatabaseFailure(ex);
+    }
+  }
+
+  /**
+   * Disconnect and return Session from current Thread.
+   * 
+   * @return Session the disconnected Session
+   */
+  static Session disconnectSession() throws DatabaseFailure {
+
+    Session session = getSession();
+    try {
+      threadSession.set(null);
+      if (session.isConnected() && session.isOpen())
+        session.disconnect();
+    } catch (HibernateException ex) {
+      throw new DatabaseFailure(ex);
+    }
+    return session;
+  }
+
+  /**
+   * Register a Hibernate interceptor with the current thread.
+   * <p>
+   * Every Session opened is opened with this interceptor after registration.
+   * Has no effect if the current Session of the thread is already open,
+   * effective on next close()/getSession().
+   */
+  static void registerInterceptor(Interceptor interceptor) {
+    threadInterceptor.set(interceptor);
+  }
+
+  private static Interceptor getInterceptor() {
+    Interceptor interceptor = (Interceptor) threadInterceptor.get();
+    return interceptor;
+  }
+
+}
+