org.glite.security.voms.admin.persistence.HibernateFactory.java Source code

Java tutorial

Introduction

Here is the source code for org.glite.security.voms.admin.persistence.HibernateFactory.java

Source

/**
 * Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2006-2016
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.glite.security.voms.admin.persistence;

import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.Properties;

import org.apache.commons.lang.Validate;
import org.glite.security.voms.admin.error.VOMSFatalException;
import org.glite.security.voms.admin.persistence.error.VOMSDatabaseException;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.cfg.Configuration;
import org.hibernate.resource.transaction.spi.TransactionStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HibernateFactory {

    private static final Logger log = LoggerFactory.getLogger(HibernateFactory.class);

    private static SessionFactory sessionFactory;

    private static Metadata metadata;

    private static final ThreadLocal<Session> threadSession = new ThreadLocal<Session>();

    private static final ThreadLocal<Transaction> threadTransaction = new ThreadLocal<Transaction>();

    public static synchronized void initialize(MetadataSources metadataSources) {
        Validate.notNull(metadataSources);

        if (sessionFactory != null) {
            throw new VOMSDatabaseException("Hibernate session factory already initialized!");
        }

        try {

            metadata = metadataSources.buildMetadata();
            sessionFactory = metadata.getSessionFactoryBuilder().build();

        } catch (Throwable e) {
            log.error("Hibernate session factory creation failed!", e);
            throw new ExceptionInInitializerError(e);
        }

    }

    public static synchronized void initialize(Configuration configuration) {

        Validate.notNull(configuration);

        if (sessionFactory != null) {
            throw new VOMSDatabaseException("Hibernate session factory already initialized!");
        }

        try {

            sessionFactory = configuration.buildSessionFactory();

        } catch (HibernateException e) {

            log.error("Hibernate session factory creation failed!", e);
            throw new ExceptionInInitializerError(e);

        }

    }

    public static synchronized void initialize(Properties databaseProperties) {

        Validate.notNull(databaseProperties);

        if (sessionFactory != null) {
            throw new VOMSDatabaseException("Hibernate session factory already initialized!");
        }

        try {

            Configuration hibernateConf = new Configuration();
            hibernateConf.addProperties(databaseProperties);

            sessionFactory = hibernateConf.configure().buildSessionFactory();

        } catch (HibernateException e) {

            log.error("Hibernate session factory creation failed!", e);
            throw new ExceptionInInitializerError(e);

        }

    }

    public static synchronized void shutdown() {

        if (sessionFactory != null) {
            sessionFactory.close();
        }

        unregisterSQLDrivers();
        cleanupThreadLocals();

    }

    protected static void unregisterSQLDrivers() {

        Enumeration<Driver> drivers = DriverManager.getDrivers();

        while (drivers.hasMoreElements()) {
            Driver driver = drivers.nextElement();
            try {

                DriverManager.deregisterDriver(driver);

            } catch (SQLException e) {
                log.warn("Error deregistering driver {}", driver, e);
            }

        }

    }

    protected static void cleanupThreadLocals() {

        if (threadSession != null) {
            threadSession.remove();
        }

        if (threadTransaction != null) {
            threadTransaction.remove();
        }

    }

    public static Metadata getMetadata() {
        return metadata;
    }

    public static SessionFactory getFactory() {

        return sessionFactory;
    }

    public static Session getSession() {

        Session s = (Session) threadSession.get();
        try {

            if (s == null) {

                s = sessionFactory.openSession();
                threadSession.set(s);

                log.debug("Opened new session for thread {}. Session: {}", Thread.currentThread(), s);
            }

        } catch (HibernateException ex) {

            log.error("Error getting hibernate session!", ex);
            throw new VOMSFatalException(ex.getMessage(), ex);
        }
        return s;
    }

    public static void closeSession() {

        try {

            Session s = (Session) threadSession.get();
            threadSession.set(null);

            if (s != null) {
                if (s.isOpen()) {
                    log.debug("Closing session for thread {}", Thread.currentThread());
                    s.close();
                } else {
                    log.debug("Session is already closed for thread {}", Thread.currentThread());
                }
            } else {
                log.debug("Attempted to close a null session for thread {}", Thread.currentThread());
            }

        } catch (HibernateException ex) {

            log.error("Error closing hibernate session!", ex);
            throw new VOMSDatabaseException(ex.getMessage(), ex);
        }
    }

    public static void beginTransaction() {

        Transaction tx = (Transaction) threadTransaction.get();
        try {

            if (tx == null) {
                tx = getSession().beginTransaction();
                threadTransaction.set(tx);

                if (log.isDebugEnabled()) {
                    log.debug("Started transation {} for thread {}. ", tx, Thread.currentThread());
                }
            }
        } catch (HibernateException ex) {

            log.error("Error creating hibernate transaction!", ex);
            throw new VOMSDatabaseException(ex.getMessage(), ex);

        }
    }

    public static void commitTransaction() {

        Transaction tx = (Transaction) threadTransaction.get();

        try {

            if (tx != null && !tx.getStatus().equals(TransactionStatus.COMMITTED)
                    && !tx.getStatus().equals(TransactionStatus.ROLLING_BACK)
                    && !tx.getStatus().equals(TransactionStatus.ROLLED_BACK)) {
                if (log.isDebugEnabled()) {
                    log.debug("Committing transaction {} for thread {}", tx, Thread.currentThread());
                }
                tx.commit();

            }

            threadTransaction.set(null);
        } catch (HibernateException ex) {
            log.error("Error committing hibernate transaction:" + ex.getMessage());

            rollbackTransaction();

            if (log.isDebugEnabled()) {
                log.error("Error committing hibernate transaction!", ex);
            }
            throw new VOMSDatabaseException(ex.getMessage(), ex);
        }
    }

    public static void rollbackTransaction() {

        Transaction tx = (Transaction) threadTransaction.get();
        TransactionStatus status = tx.getStatus();
        log.warn("Rolling back transaction {}", tx);
        try {

            threadTransaction.set(null);
            if (tx != null && !tx.getStatus().equals(TransactionStatus.COMMITTED)
                    && !tx.getStatus().equals(TransactionStatus.ROLLING_BACK)
                    && !tx.getStatus().equals(TransactionStatus.ROLLED_BACK)) {

                if (log.isDebugEnabled()) {
                    log.debug("Rolling back transaction {} for thread {}", tx, Thread.currentThread());
                }
                tx.rollback();
            }
        } catch (HibernateException ex) {
            log.error("Error rolling back hibernate transaction:" + ex.getMessage(), ex);

            throw new VOMSDatabaseException(ex.getMessage(), ex);

        } finally {
            closeSession();
        }

    }
}