Differences between revisions 1 and 2
Revision 1 as of 2005-09-26 12:28:07
Size: 10095
Comment:
Revision 2 as of 2009-09-20 22:01:40
Size: 10095
Editor: localhost
Comment: converted to 1.6 markup
No differences found!

package scm.hivemind.hibernate;

import java.io.InputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.Transaction;
import net.sf.hibernate.cfg.Configuration;
import net.sf.hibernate.tool.hbm2ddl.SchemaUpdate;

import org.apache.commons.logging.Log;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.Discardable;
import org.apache.hivemind.PoolManageable;
import org.apache.hivemind.Resource;
import org.apache.hivemind.ServiceImplementationFactory;
import org.apache.hivemind.ServiceImplementationFactoryParameters;
import org.apache.hivemind.events.RegistryShutdownListener;
import org.apache.hivemind.service.ThreadEventNotifier;

import scm.hivemind.statefulservice.StatefulServiceLifecycleListener;

/**
 *  Die Klasse HibernateSessionFactory ist eine Hivemind-ServiceImplementationFactory
 * die Hibernate-Session-Proxies zur Verwendung als Hivemind-Services produziert.
 * 
 * @author schultma
 */
public class HibernateSessionFactory 
    implements ServiceImplementationFactory, RegistryShutdownListener
  {
    private SessionFactory sessionFactory;
    private Transaction transaction;
    private ThreadEventNotifier threadEventNotifier;
    private boolean updateSchema = false;
    private boolean transactionManager = false;
    protected Log log;
    private String configFile;
    private String jndiName;
    private Properties hibProps = new Properties();

    public HibernateSessionFactory( List config ) {
        for ( Iterator it = config.iterator(); it.hasNext(); ) {
            HibernateProperty cfgProp = (HibernateProperty) it.next();
            if ( cfgProp instanceof HibernateConfigFile )
                configFile = cfgProp.getName();
            else
                hibProps.setProperty( "hibernate."+ cfgProp.getName(), 
                                                   cfgProp.getValue() );
        }
        
    }
    
    public void init()
    {
      try {
          log.debug( "Initializing Hibernate SessionFactory..." );
          Configuration config =  new Configuration() {
              /* Make sure, we use the current Classloader for Configs ...
               * @see net.sf.hibernate.cfg.Configuration#getConfigurationInputStream(java.lang.String)
               */
              protected InputStream getConfigurationInputStream( String resource )
                      throws HibernateException {
                  InputStream stream = null;
                  stream = getClass().getResourceAsStream( resource );
                  if (stream == null) {
                    throw new HibernateException(resource + " not found");
                  }
                  return stream;
              }
          };

          config.configure( configFile );
          config.setProperties( hibProps );

          if( updateSchema )
          {
            log.debug( "Updating database schema..." );
            new SchemaUpdate( config ).execute( true, true );
          }
          sessionFactory = config.buildSessionFactory();
            } catch ( Exception e ) {
               throw new ApplicationRuntimeException(e);
            } 
    }

    public Object createCoreServiceImplementation
                        ( ServiceImplementationFactoryParameters params )
    {
      try {
         log.debug( "Creating Hibernate Session..." );
         Session session = sessionFactory.openSession();
          
          Object proxy = Proxy.newProxyInstance(
                  params.getInvokingModule().getClassResolver().getClassLoader(),
                  new Class[]{ params.getServiceInterface(), 
                               StatefulServiceLifecycleListener.class,
                               Discardable.class, 
                               PoolManageable.class }, 
                  new SessionProxy( session ) );
          
          //threadEventNotifier.addThreadCleanupListener(new SessionCloser(session));
          return proxy;
      } catch ( Exception e ) {
          throw new ApplicationRuntimeException(e);
      }
    }

    public void registryDidShutdown()
    {
                 try {
            log.debug( "Closing Hibernate SessionFactory..." );
             sessionFactory.close();
        } catch ( HibernateException e ) {
            throw new ApplicationRuntimeException(e);
        }
    }

    public void setThreadEventNotifier(ThreadEventNotifier notifier)
    {
      this.threadEventNotifier = notifier;
    }

    public void setLog( Log log )
    {
      this.log = log;
    }

    public void setJndiName( String jn ){
        jndiName = jn;
    }
    
    public void setUpdateSchema( boolean updateSchema )
    {
      this.updateSchema = updateSchema;
    }
    public boolean isTransactionManager() {
        return transactionManager;
    }
    public void setTransactionManager( boolean showSql ) {
        this.transactionManager = showSql;
    }
    
    /**
     *  Instanzen der Klasse SessionProxy sind Adapter für Hibernate-Sessions.
     * Sie setzen die Hivemind-Lifecycle-Events
     * in die richtigen Methodenaufrufe der Hibernate-Session um.
     * Es werden die Service-Modelle "pooled", "threaded" und "stateful" 
     * unterstützt.
     */
    private class SessionProxy implements InvocationHandler, 
                                                                      StatefulServiceLifecycleListener,
                                                                      PoolManageable, 
                                                                      Discardable {
        private Session session;
        public SessionProxy( Session session ) {
                   log.debug("creating hibernate session proxy");
            this.session = session;
            try {
                                startTransactionIfNecessary();
                        } catch (HibernateException e) {
                                throw new ApplicationRuntimeException(e); 
                        }            
        }
        /* (non-Javadoc)
         * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
         */
        public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable {
            if (method.getDeclaringClass().equals(Session.class))
                return method.invoke( session, args );
            else if ( method.getDeclaringClass().equals(StatefulServiceLifecycleListener.class) 
                     || method.getDeclaringClass().equals(PoolManageable.class)
                     || method.getDeclaringClass().equals(Object.class)) {
                return method.invoke( this, args );
            } else
                throw new ApplicationRuntimeException("unable to interprete msg "
                         + method.getName() );
        }

        public void terminateConversation() {
            try {
                log.debug("throwing session away");
                if ( session != null && session.isOpen() ) {
                           endTransactionIfNecessary();
                    session.close();
                    session = null;
                }
            } catch ( HibernateException e ) {
                throw new ApplicationRuntimeException(e);
            }
        }
        
        
        public void resumeConversation() {
            try {
                log.debug("reconnecting session");
                if (!session.isConnected())
                    session.reconnect();
                startTransactionIfNecessary();
            } catch ( HibernateException e ) {
                throw new ApplicationRuntimeException(e);
            }
        }

       
                public void pauseConversation() {
            try {
                log.debug("disconnecting session");
                if (session.isConnected()) {
                           endTransactionIfNecessary();                         
                    session.disconnect();
                }
            } catch ( HibernateException e ) {
                throw new ApplicationRuntimeException(e);
            }
        }
        
                 
        /**
                 * @throws HibernateException
                 */
                private void startTransactionIfNecessary() throws HibernateException {
                        if ( isTransactionManager() && transaction == null )
                                   transaction = session.beginTransaction();
                }
        
        /**
                 * @throws HibernateException
                 */
                private void endTransactionIfNecessary() throws HibernateException {
                        if ( isTransactionManager() && transaction != null 
                                        && ! transaction.wasRolledBack() 
                            && ! transaction.wasCommitted()  ) {
                                  transaction.commit();
                                  transaction = null;
                           }
                }
                public String toString() {
            return super.toString() + " - proxy for " + session.toString();
        }
        
        /* (non-Javadoc)
         * @see org.apache.hivemind.PoolManageable#activateService()
         */
        public void activateService() {
           // acquire new Hibernate-Session
            log.debug( "Creating Hibernate Session..." );
            try {
                session = getSessionFactory().openSession();
                startTransactionIfNecessary();
            } catch ( HibernateException e ) {
                throw new ApplicationRuntimeException(e);
            }
             
        }
        /* (non-Javadoc)
         * @see org.apache.hivemind.PoolManageable#passivateService()
         */
        public void passivateService() {
           //throw away Hibernate-Session
           terminateConversation();
        }
        /* (non-Javadoc)
         * @see org.apache.hivemind.Discardable#threadDidDiscardService()
         */
        public void threadDidDiscardService() {
           terminateConversation();
        }
    }
  
   
    protected SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

HibernateSessionFactory (last edited 2009-09-20 22:01:40 by localhost)