org.siberia.binding.impl.db.hibernate.HibernateBindingManager.java Source code

Java tutorial

Introduction

Here is the source code for org.siberia.binding.impl.db.hibernate.HibernateBindingManager.java

Source

/* 
 * Siberia binding : siberia plugin defining persistence services
 *
 * Copyright (C) 2008 Alexis PARIS
 * Project Lead:  Alexis Paris
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * 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.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library;
 * if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 */
package org.siberia.binding.impl.db.hibernate;

import java.io.Serializable;
import java.net.URL;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import org.apache.log4j.Logger;
import org.hibernate.CallbackException;
import org.hibernate.EmptyInterceptor;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.classic.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.event.InitializeCollectionEvent;
import org.hibernate.event.PostLoadEvent;
import org.hibernate.event.PreDeleteEvent;
import org.hibernate.event.PreLoadEvent;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;
import org.hibernate.type.Type;
import org.siberia.TypeInformationProvider;
import org.siberia.binding.constraint.DataBaseBindingConstraint;
import org.siberia.binding.exception.DatabaseConfigurationException;
import org.siberia.binding.exception.SaveException;
import org.siberia.binding.impl.db.*;
import org.siberia.binding.transaction.Transaction;
import org.siberia.type.SibType;
import org.siberia.ResourceLoader;

/**
 *
 * DataBaseBindingManager based on hibernate framework
 *
 * @author alexis
 */
public class HibernateBindingManager extends AbstractDataBaseBindingManager<HibernateTransactionHandler> {
    /** property hibernate dialect */
    public static final String PROPERTY_DIALECT = "hibernate.dialect";

    /** property hibernate hbm2ddl auto */
    public static final String PROPERTY_HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";

    /** property factory */
    public static final String PROPERTY_FACTORY_CLASS = "hibernate.jdbc.factory_class";// "transaction.factory_class";

    /** session context class */
    public static final String PROPERTY_SESSION_CONTEXT_CLASS = "hibernate.current_session_context_class";

    /** isolation */
    public static final String PROPERTY_ISOLATION = "hibernate.connection.isolation";

    /** connection release mode */
    public static final String PROPERTY_CONNECTION_RELEASE_MODE = "hibernate.connection.release_mode";

    /** batch size */
    public static final String PROPERTY_BATCH_SIZE = "hibernate.jdbc.batch_size";

    /** auto commit property */
    public static final String PROPERTY_AUTO_COMMIT = "hibernate.connection.autocommit";

    /** auto close session */
    public static final String PROPERTY_AUTO_CLOSE_SESSION = "hibernate.transaction.auto_close_session";

    /** show sql */
    public static final String PROPERTY_SHOW_SQL = "hibernate.show_sql";

    /** format sql */
    public static final String PROPERTY_FORMAT_SQL = "hibernate.format_sql";

    /** logger */
    public Logger logger = Logger.getLogger(HibernateBindingManager.class);

    /** session factory */
    private SessionFactory sessionFactory = null;

    /** configuration */
    private Configuration configuration = null;

    /** Creates a new instance of HibernateBindingManager */
    public HibernateBindingManager() throws DatabaseConfigurationException {
        this.configuration = this.createConfiguration();

        //   org.hibernate.event.PreLoadEventListener preLoadListener = new org.hibernate.event.PreLoadEventListener()
        //   {
        //       public void onPreLoad(PreLoadEvent event)
        //       {
        //      System.err.println("############# onPreLoad");
        //      System.err.println("############# onPreLoad");
        //      System.err.println("############# onPreLoad");
        //      System.err.println("############# onPreLoad");
        //      System.err.println("############# onPreLoad");
        //       }
        //   };
        //   configuration.setListener("pre-load", preLoadListener);
        //   
        //   org.hibernate.event.PostLoadEventListener postLoadListener = new org.hibernate.event.PostLoadEventListener()
        //   {
        //       public void onPostLoad(PostLoadEvent event)
        //       {
        //      System.err.println("############# onPostLoad");
        //      System.err.println("############# onPostLoad");
        //      System.err.println("############# onPostLoad");
        //      System.err.println("############# onPostLoad");
        //      System.err.println("############# onPostLoad");
        //       }
        //   };
        //   configuration.setListener("post-load", postLoadListener);
        //   
        //   org.hibernate.event.InitializeCollectionEventListener collecListener = new org.hibernate.event.InitializeCollectionEventListener()
        //   {
        //       public void onInitializeCollection(InitializeCollectionEvent event) throws HibernateException
        //       {
        //      System.err.println("############# onInitializeCollection");
        //      System.err.println("############# onInitializeCollection");
        //      System.err.println("############# onInitializeCollection");
        //      System.err.println("############# onInitializeCollection");
        //      System.err.println("############# onInitializeCollection");
        //       }
        //   };
        //   configuration.setListener("load-collection", collecListener);

        //   public void setListeners(String type, Object[] listeners) {
        //                        "auto-flush"
        //                        "merge"
        //                        "create"
        //                        "create-onflush"
        //                        "delete"
        //                        "dirty-check"
        //                        "evict"
        //                        "flush"
        //                        "flush-entity"
        //           "load"
        //                        "load-collection"
        //                        "lock"
        //                        "refresh"
        //                        "replicate"
        //                        "save-update"
        //                        "save"
        //                        "update"
        //                        "pre-load"
        //                        "pre-update"
        //                        "pre-delete"
        //                        "pre-insert"
        //                        "post-load"
        //                        "post-update"
        //                        "post-delete"
        //                        "post-insert"
        //                        "post-commit-update"
        //                        "post-commit-delete"
        //                        "post-commit-insert"
        /////////////////////
        //        configuration.EventListeners().

        //   configuration = configuration.setInterceptor(new EmptyInterceptor()
        //   {
        //       public void afterTransactionBegin(org.hibernate.Transaction tx)
        //       {
        //      System.err.println("interceptor :: afterTransactionBegin");
        //      super.afterTransactionBegin(tx);
        //       }
        //       public void afterTransactionCompletion(org.hibernate.Transaction tx)
        //       {
        //      System.err.println("interceptor :: afterTransactionCompletion");
        //      super.afterTransactionCompletion(tx);
        //       }
        //       public void beforeTransactionCompletion(org.hibernate.Transaction tx)
        //       {
        //      System.err.println("interceptor :: beforeTransactionCompletion");
        //      super.beforeTransactionCompletion(tx);
        //       }
        //       public int[] findDirty(Object entity, Serializable id, Object[]
        //          currentState, Object[] previousState, String[] propertyNames, Type[] types)
        //       {
        //      System.err.println("interceptor :: findDirty");
        //      return super.findDirty(entity, id, currentState, previousState, propertyNames, types);
        //       }
        //       public Object getEntity(String entityName, Serializable id) throws CallbackException
        //       {
        //      System.err.println("interceptor :: getEntity");
        //      return super.getEntity(entityName, id);
        //       }
        //       public String getEntityName(Object object) throws CallbackException
        //       {
        //      System.err.println("interceptor :: getEntityName");
        //      return super.getEntityName(object);
        //       }
        //       public Object instantiate(String entityName, EntityMode entityMode, Serializable id) throws CallbackException
        //       {
        //      System.err.println("interceptor :: instantiate");
        //      return super.instantiate(entityName, entityMode, id);
        //       }
        //       public Boolean isTransient(Object entity)
        //       {
        //      System.err.println("interceptor :: isTransient");
        //      return super.isTransient(entity);
        //       }
        //       public void onCollectionRecreate(Object collection, Serializable key) throws CallbackException
        //       {
        //      System.err.println("interceptor :: onCollectionRecreate");
        //      super.onCollectionRecreate(collection, key);
        //       }
        //       public void onCollectionRemove(Object collection, Serializable key) throws CallbackException
        //       {
        //      System.err.println("interceptor :: onCollectionRemove");
        //      super.onCollectionRemove(collection, key);
        //       }
        //       public void onCollectionUpdate(Object collection, Serializable key) throws CallbackException
        //       {
        //      System.err.println("interceptor :: onCollectionUpdate");
        //      super.onCollectionUpdate(collection, key);
        //       }
        //       public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException
        //       {
        //      System.err.println("interceptor :: onDelete");
        //      super.onDelete(entity, id, state, propertyNames, types);
        //       }
        //       public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, 
        //               Object[] previousState, String[] propertyNames, 
        //               Type[] types) throws CallbackException
        //       {
        //      System.err.println("interceptor :: onFlushDirty");
        //      return super.onFlushDirty(entity, id, currentState, 
        //               previousState, propertyNames, 
        //               types);
        //       }
        //       public boolean onLoad(Object entity, Serializable id, Object[] state, 
        //              String[] propertyNames, Type[] types) throws CallbackException
        //       {
        //      System.err.println("interceptor :: onLoad");
        //      return super.onLoad(entity, id, state, propertyNames, types);
        //       }
        //       public String onPrepareStatement(String sql)
        //       {
        //      System.err.println("interceptor :: onPrepareStatement");
        //      return super.onPrepareStatement(sql);
        //       }
        //       public boolean onSave(Object entity, Serializable id, Object[] state,
        //              String[] propertyNames, Type[] types) throws CallbackException
        //       {
        //      System.err.println("interceptor :: onSave");
        //      return super.onSave(entity, id, state, propertyNames, types);
        //       }
        //       public void postFlush(Iterator entities) throws CallbackException
        //       {
        //      System.err.println("interceptor :: postflush");
        //      super.postFlush(entities);
        //       }
        //       public void preFlush(Iterator entities) throws CallbackException
        //       {
        //      System.err.println("interceptor :: preFlush");
        //      super.preFlush(entities);
        //       }
        //   });

        try {
            /* Create the SessionFactory */
            this.sessionFactory = this.configuration.buildSessionFactory();
        } catch (Exception ex) { // Make sure you log the exception, as it might be swallowed
            logger.error("Initial SessionFactory creation failed." + ex);
            ex.printStackTrace();
        }

        //   Hibernate.initialize(null);
        //   ThreadLocalSessionContext
        //   org.hibernate.impl.SessionFactoryImpl

        //   Iterator it = configuration.getTableMappings();
        //   System.out.println("table mappings : ");
        //   while(it.hasNext())
        //   {
        //       Object current = it.next();
        //       System.out.println("\t" + current + " of kind : " + current.getClass());
        //       
        //       if ( current instanceof org.hibernate.mapping.Table )
        //       {
        //      org.hibernate.mapping.Table table = (org.hibernate.mapping.Table)current;
        ////      configuration.get
        ////      String sqlDel = table.sqlDropString(null, table.getCatalog(), table.getSchema());
        ////      System.out.println("toDelete : " + sqlDel);
        //       }
        //   }

        //   org.hibernate.mapping.Table(ABSTRACT_TAGGED_SONG_ITEM) of kind : class org.hibernate.mapping.Table
        //        org.hibernate.mapping.Table(AUDIO_ITEM) of kind : class org.hibernate.mapping.Table
        //        org.hibernate.mapping.Table(DEFAULT_SONG_ITEM) of kind : class org.hibernate.mapping.Table
        //        org.hibernate.mapping.Table(IGNORED_DIRECTORIES) of kind : class org.hibernate.mapping.Table
        //        org.hibernate.mapping.Table(MP3_SONG_ITEM) of kind : class org.hibernate.mapping.Table
        //        org.hibernate.mapping.Table(PLAYLIST) of kind : class org.hibernate.mapping.Table
        //        org.hibernate.mapping.Table(PLAYLIST_ITEMS) of kind : class org.hibernate.mapping.Table
        //        org.hibernate.mapping.Table(RADIO_ITEM) of kind : class org.hibernate.mapping.Table
        //        org.hibernate.mapping.Table(SCANNABLE_PLAYLIST) of kind : class org.hibernate.mapping.Table
        //        org.hibernate.mapping.Table(SCANNED_DIRECTORIES) of kind : class org.hibernate.mapping.Table
        //        org.hibernate.mapping.Table(SONG_ITEM) of kind : class org.hibernate.mapping.Table

        this.ensureTableCreations();
    }

    /** drop all databases tables */
    public void dropAllTables() {
        SchemaExport export = new SchemaExport(this.configuration);
        export.drop(false, true);

        List exceptions = export.getExceptions();
        if (exceptions != null) {
            for (int i = 0; i < exceptions.size(); i++) {
                Object current = exceptions.get(i);

                if (current instanceof Throwable) {
                    logger.error("exception occured while droping tables", (Throwable) current);
                }
            }
        }
    }

    /** ensure that all tables are created */
    private void ensureTableCreations() {
        SchemaUpdate update = new SchemaUpdate(this.configuration);
        update.execute(true, true);

        List exceptions = update.getExceptions();
        if (exceptions != null) {
            for (int i = 0; i < exceptions.size(); i++) {
                Object current = exceptions.get(i);

                if (current instanceof Throwable) {
                    logger.error("exception occured while updating schema", (Throwable) current);
                }
            }
        }
    }

    /** create all databases tables */
    public void createAllTables() {
        this.ensureTableCreations();
    }

    /** return the session factory
     *  @return a SessionFactory
     */
    public SessionFactory getSessionFactory() {
        return this.sessionFactory;
    }

    /** method that returns the configuration to use
     *  @return a Configuration
     */
    private Configuration createConfiguration() {
        Configuration cfg = new Configuration();

        List<Class> classes = TypeInformationProvider.getInstance().getSubClassFor(SibType.class, true, true, true,
                (Class[]) null);

        if (classes != null) {
            String suffix = ".hbm.xml";

            for (int i = 0; i < classes.size(); i++) {
                Class current = classes.get(i);

                if (current != null) {
                    String pluginId = TypeInformationProvider.getInstance().getPluginDeclaring(current);

                    if (pluginId == null) {
                        logger.warn("could not find the plugin declaring class " + current);
                    } else {
                        StringBuffer buffer = new StringBuffer(current.getName().length() + suffix.length());

                        buffer.append(current.getName());

                        /** replace . by / */
                        for (int j = 0; j < buffer.length(); j++) {
                            char currentChar = buffer.charAt(j);

                            if (currentChar == '.') {
                                buffer.deleteCharAt(j);
                                buffer.insert(j, '/');
                            }
                        }
                        buffer.append(suffix);

                        URL url = ResourceLoader.getInstance().getPluginClassLoader(pluginId)
                                .getResource(buffer.toString());

                        if (url == null) {
                            logger.warn("resource " + buffer.toString() + " could not be found --> ignored");
                        } else {
                            logger.info("adding hibernate mapping declaration from " + url);
                            cfg = cfg.addURL(url);
                        }
                    }
                }
            }
        }

        /** configure Configuration properties */

        Properties convertedProperties = this.convertProperties(this.getProperties());

        this.reportIgnoredProperties();

        Enumeration en = convertedProperties.keys();
        while (en.hasMoreElements()) {
            Object current = en.nextElement();

            logger.debug(
                    "consider database property '" + current + "' --> '" + convertedProperties.get(current) + "'");
        }

        cfg = cfg.setProperties(convertedProperties);

        return cfg;
    }

    /** convert properties specified for jdo
     *  @param initialProperties
     *  @return a Properties
     */
    protected Properties convertProperties(Properties initialProperties) {
        Properties result = null;

        if (initialProperties != null) {
            result = new Properties();
            Enumeration en = initialProperties.propertyNames();

            while (en.hasMoreElements()) {
                Object current = en.nextElement();

                if (current instanceof String) {
                    boolean processed = true;

                    String value = initialProperties.getProperty((String) current);
                    if (current.equals(PROPERTY_CONNECTION_DRIVER_NAME)) {
                        result.put("hibernate.connection.driver_class", value);
                    } else if (current.equals(PROPERTY_CONNECTION_URL)) {
                        result.put("hibernate.connection.url", value);
                    } else if (current.equals(PROPERTY_CONNECTION_USERNAME)) {
                        result.put("hibernate.connection.username", value);
                    } else if (current.equals(PROPERTY_CONNECTION_PASSWORD)) {
                        result.put("hibernate.connection.password", value);
                    } else if (current.equals(PROPERTY_DIALECT)) {
                        result.put(PROPERTY_DIALECT, value);
                    } else if (current.equals(PROPERTY_HBM2DDL_AUTO)) {
                        result.put(PROPERTY_HBM2DDL_AUTO, value);
                    } else if (current.equals(PROPERTY_FACTORY_CLASS)) {
                        result.put(PROPERTY_FACTORY_CLASS, value);
                    } else if (current.equals(PROPERTY_SESSION_CONTEXT_CLASS)) {
                        result.put(PROPERTY_SESSION_CONTEXT_CLASS, value);
                    } else if (current.equals(PROPERTY_ISOLATION)) {
                        result.put(PROPERTY_ISOLATION, value);
                    } else if (current.equals(PROPERTY_CONNECTION_RELEASE_MODE)) {
                        result.put(PROPERTY_CONNECTION_RELEASE_MODE, value);
                    } else if (current.equals(PROPERTY_BATCH_SIZE)) {
                        result.put(PROPERTY_BATCH_SIZE, value);
                    } else if (current.equals(PROPERTY_AUTO_COMMIT)) {
                        result.put(PROPERTY_AUTO_COMMIT, value);
                    } else if (current.equals(PROPERTY_AUTO_CLOSE_SESSION)) {
                        result.put(PROPERTY_AUTO_CLOSE_SESSION, value);
                    } else if (current.equals(PROPERTY_SHOW_SQL)) {
                        result.put(PROPERTY_SHOW_SQL, value);
                    } else if (current.equals(PROPERTY_FORMAT_SQL)) {
                        result.put(PROPERTY_FORMAT_SQL, value);
                    } else if (((String) current).startsWith("hibernate.c3p0")) {
                        result.put(current, value);
                    } else {
                        processed = false;
                    }

                    if (processed) {
                        this.setPropertyAsProcessed((String) current);
                    }
                }
            }
        }

        return result;
    }

    /**
     * shutdown manager
     *  close all resources opened by the manager including database connections
     */
    public void shutdown() {
        if (this.sessionFactory != null) {
            this.sessionFactory.close();
            this.sessionFactory = null;
        }
    }

    /** ########################################################################
     *  ######################### data management ##############################
     *  ######################################################################## */

    /** create a new Transaction
     *   @return a new transaction
     */
    public HibernateTransactionHandler createTransaction() throws Exception {
        HibernateTransactionHandler tr = null;

        Session session = this.sessionFactory.getCurrentSession();
        //   Session                   session     = this.sessionFactory.openSession();
        org.hibernate.Transaction transaction = session.beginTransaction();

        tr = new HibernateTransactionHandler(session, transaction);

        return tr;
    }

    /** return true if the item exists
     *   @param transaction a Transaction
     *   @param object the object to check
     *   @return true if the object exists
     */
    public boolean exists(HibernateTransactionHandler transaction, Object object) throws Exception {
        /* not yet implemented */
        return false;
    }

    /**
     * save objects in database
     * 
     *   @param transaction a Transaction
     *  @param types an array of Object
     *  @exception SaveException if errors occured
     */
    public void store(HibernateTransactionHandler transaction, Object... types) throws Exception {
        if (types != null) {
            try {
                for (int i = 0; i < types.length; i++) {
                    transaction.getSession().saveOrUpdate(types[i]);
                }
            } catch (Exception e) {
                transaction.setRollbackOnly();
                throw e;
            }
        }
    }

    /** load objects
     *  @param transaction a Transaction
     *   @param kind a Class that represents the kind of item to load
     *  @param constraints an array of BindingConstraint that allow to filter objects to load
     *   @return a list of Objects resulting from the loading process
     */
    public List load(HibernateTransactionHandler transaction, Class kind, DataBaseBindingConstraint... constraints)
            throws Exception {
        List results = null;

        StringBuffer queryBuffer = new StringBuffer();
        queryBuffer.append("from " + kind.getSimpleName());

        try {
            Query query = null;

            /** complete query with constraint */
            if (constraints != null) {
                boolean whereAdded = false;

                for (int i = 0; i < constraints.length; i++) {
                    DataBaseBindingConstraint ctr = constraints[i];

                    if (ctr != null && ctr.isActive()) {
                        if (!whereAdded) {
                            queryBuffer.append((" WHERE"));

                            whereAdded = true;
                        }

                        /** find the hibernate name of the property linked to ctr.getPropertyName() */
                        String hibernatePropertyName = ctr.getPropertyName();

                        queryBuffer.append(
                                " " + hibernatePropertyName + " " + ctr.getRelation().getDatabaseValue() + " ");

                        Object constraint = ctr.getConstraintValue();
                        if (constraint instanceof String) {
                            queryBuffer.append("'" + ((String) constraint) + "'");
                        } else {
                            queryBuffer.append(constraint.toString());
                        }
                    }
                }
            }

            query = transaction.getSession().createQuery(queryBuffer.toString());
            results = query.list();
        } catch (HibernateException e) {
            transaction.setRollbackOnly();
            throw e;
        }

        return results;
    }

    /**
     * refresh the status of an object stored in database
     * 
     *  @param transaction a Transaction
     *  @param type an Object
     */
    public void refresh(HibernateTransactionHandler transaction, Object type) throws Exception {

    }

    /**
     * delete objects in database
     * 
     *  @param transaction a Transaction
     *  @param types an array of Object
     */
    public void delete(HibernateTransactionHandler transaction, Object... types) throws Exception {
        if (types != null) {
            for (int i = 0; i < types.length; i++) {
                Object current = types[i];

                if (current != null) {
                    try {
                        transaction.getSession().delete(current);
                    } catch (HibernateException e) {
                        transaction.setRollbackOnly();
                        throw e;
                    }
                }
            }
        }
    }

    /** return a Collection of items that convey to given critera
     *  @param transaction a Transaction
     *  @param typeClass the kind of item to load
     *  @param subclasses whether to include instances of subclasses
     */
    public int getItemsCount(HibernateTransactionHandler transaction, Class typeClass, boolean subClasses)
            throws Exception {
        return 0;
    }

}