gr.interamerican.bo2.impl.open.hibernate.HibernateConfigurations.java Source code

Java tutorial

Introduction

Here is the source code for gr.interamerican.bo2.impl.open.hibernate.HibernateConfigurations.java

Source

/*******************************************************************************
 * Copyright (c) 2013 INTERAMERICAN PROPERTY AND CASUALTY INSURANCE COMPANY S.A.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v3
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/copyleft/lesser.html
 * 
 * This library 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 Lesser General Public License for more details.
 ******************************************************************************/
package gr.interamerican.bo2.impl.open.hibernate;

import gr.interamerican.bo2.arch.exceptions.InitializationException;
import gr.interamerican.bo2.impl.open.hibernate.tuple.Bo2PojoEntityTuplizer;
import gr.interamerican.bo2.impl.open.hibernate.tuple.resolver.Bo2EntityNameResolver;
import gr.interamerican.bo2.utils.ReflectionUtils;
import gr.interamerican.bo2.utils.StreamUtils;
import gr.interamerican.bo2.utils.StringConstants;
import gr.interamerican.bo2.utils.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.impl.SessionFactoryImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This class manages all hibernate configurations and their SessionFactory
 * objects.
 */
public class HibernateConfigurations {

    /**
     * Logger.
     */
    private static Logger LOGGER = LoggerFactory.getLogger(HibernateConfigurations.class);

    /**
     * Schema property on a hibernate config.
     */
    static final String SCHEMA_PROPERTY = "hibernate.default_schema"; //$NON-NLS-1$

    /**
     * Static map that stores all session factories, mapped to the path
     * of their configuration files.
     */
    static Map<String, SessionFactory> sessionFactories = new HashMap<String, SessionFactory>();

    /**
     * Gets the session factory that corresponds to the specified configuration
     * file.
     * 
     * @param pathToCfg
     *        Path to the configuration resource file.
     * @param dbSchema
     *        Db schema.
     * @param sessionInterceptor
     *        Hibernate session interceptor.
     * @param hibernateMappingsPath
     *        Path to file that lists files indexing hbm files this session factory
     *        should be configured with.
     * 
     * @return Returns the session factory.
     * 
     * @throws InitializationException
     *         If the creation of the session factory fails.
     */
    public static synchronized SessionFactory getSessionFactory(String pathToCfg, String dbSchema,
            String sessionInterceptor, String hibernateMappingsPath) throws InitializationException {
        SessionFactory sessionFactory = sessionFactories.get(key(pathToCfg, dbSchema));
        if (sessionFactory == null) {
            sessionFactory = createSessionFactory(pathToCfg, dbSchema, sessionInterceptor, hibernateMappingsPath);
            sessionFactories.put(key(pathToCfg, dbSchema), sessionFactory);
        }
        return sessionFactory;
    }

    /**
     * Closes opened session factories. A web application should call this before
     * unloading or stopping.
     */
    public static void flushConfigurations() {
        for (Map.Entry<String, SessionFactory> e : sessionFactories.entrySet()) {
            e.getValue().close();
        }
        sessionFactories.clear();
    }

    /**
     * Creates a SessionFactory.
     * 
     * @param pathToCfg
     *        Path to the hibernate configuration file.
     * @param dbSchema
     *        Db schema.
     * @param sessionInterceptor
     *        Hibernate session interceptor.
     * @param hibernateMappingsPath
     *        Path to file that lists files indexing hbm files this session factory
     *        should be configured with
     * 
     * @return Returns the session factory.
     * 
     * @throws InitializationException
     *         If the creation of the SessionFactory fails.
     */
    @SuppressWarnings("nls")
    static SessionFactory createSessionFactory(String pathToCfg, String dbSchema, String sessionInterceptor,
            String hibernateMappingsPath) throws InitializationException {
        try {
            Configuration conf = new Configuration();

            Interceptor interceptor = getInterceptor(sessionInterceptor);
            if (interceptor != null) {
                conf.setInterceptor(interceptor);
            }

            conf.setProperty(SCHEMA_PROPERTY, dbSchema);

            List<String> hbms = getHibernateMappingsIfAvailable(hibernateMappingsPath);
            for (String entityMapping : hbms) {
                LOGGER.debug("Adding " + entityMapping + " to the session factory configuration.");
                conf.addResource(entityMapping);
            }

            conf.configure(pathToCfg);

            conf.getEntityTuplizerFactory().registerDefaultTuplizerClass(EntityMode.POJO,
                    Bo2PojoEntityTuplizer.class);
            SessionFactory sessionFactory = conf.buildSessionFactory();
            ((SessionFactoryImpl) sessionFactory).registerEntityNameResolver(Bo2EntityNameResolver.INSTANCE,
                    EntityMode.POJO);
            sessionFactory.getStatistics().setStatisticsEnabled(true);
            return sessionFactory;
        } catch (HibernateException e) {
            throw new InitializationException(e);
        }
    }

    /**
     * Get the interceptor instance if it is configured.
     * @param sessionInterceptor
     * @return Interceptor instance.
     */
    private static Interceptor getInterceptor(String sessionInterceptor) {
        if (StringUtils.isNullOrBlank(sessionInterceptor)) {
            return null;
        }
        return ReflectionUtils.newInstance(sessionInterceptor);
    }

    /**
     * @param pathToCfg
     * @param dbSchema
     * @return Returns a key for local caching.
     */
    private static String key(String pathToCfg, String dbSchema) {
        return pathToCfg + StringConstants.UNDERSCORE + dbSchema;
    }

    /**
     * Extracts a list of hibernate mapping files given a resource path.
     * The resource path points to a file. The file is plain text and
     * each line contains one resource path that points to an hbm.xml file
     * or another file that indexes hbms.
     * If an indexed hdm.xml file does not exist on the classpath an error
     * is logged, but no exception is thrown. This is meant to facilitate
     * tests that need to create a SessionFactory and do not have all indexed
     * hibernate mapping files in their running classpath.
     * If the indexed file does not have the hbm.xml extension, the system
     * attempts to read it and treats it as an hbm.xml files index.
     *
     * @see BOTWO-48
     * 
     * @param managerHbmIndex
     *        Resource path. Null tolerant.
     * 
     * @return Indexed hbm files resource paths.
     */
    @SuppressWarnings("nls")
    static List<String> getHibernateMappingsIfAvailable(String managerHbmIndex) {
        List<String> hbms = new ArrayList<String>();

        if (StringUtils.isNullOrBlank(managerHbmIndex)) {
            return hbms;
        }

        String[] hbmPaths = null;
        try {
            hbmPaths = StreamUtils.readResourceFile(managerHbmIndex, true, true);
        } catch (IOException ioe) {
            throw new RuntimeException(ioe);
        }

        if (hbmPaths == null) {
            String msg = StringUtils.concat("Non existant hibernate mappings index: ", managerHbmIndex,
                    ". This is acceptable for unit tests, but FATAL in every other case and should be investigated.");
            LOGGER.warn(msg);
            return hbms;
        }

        for (String hbmPath : hbmPaths) {
            String[] hbmContent = null;

            try {
                hbmContent = StreamUtils.readResourceFile(StringConstants.SLASH + hbmPath.trim(), true, true);
            } catch (IOException ioe) {
                throw new RuntimeException(ioe);
            }

            if (hbmContent == null) {
                String msg = StringUtils.concat("Non existant hibernate mappings file or index: ", hbmPath,
                        ". This is acceptable for unit tests, but FATAL in every other case and should be investigated.");
                LOGGER.warn(msg);
                continue;
            }

            if (hbmPath.trim().endsWith("hbm.xml")) {
                hbms.add(hbmPath);
            } else {
                hbms.addAll(getHibernateMappingsIfAvailable(hbmPath));
            }

        }

        return hbms;
    }

}