Package org.hibernate.ejb

Source Code of org.hibernate.ejb.EventListenerConfigurator

//$Id: EventListenerConfigurator.java 14393 2008-03-06 16:50:07Z epbernard $
package org.hibernate.ejb;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;

import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.ejb.event.CallbackHandlerConsumer;
import org.hibernate.ejb.event.EJB3AutoFlushEventListener;
import org.hibernate.ejb.event.EJB3DeleteEventListener;
import org.hibernate.ejb.event.EJB3FlushEntityEventListener;
import org.hibernate.ejb.event.EJB3FlushEventListener;
import org.hibernate.ejb.event.EJB3MergeEventListener;
import org.hibernate.ejb.event.EJB3PersistEventListener;
import org.hibernate.ejb.event.EJB3PersistOnFlushEventListener;
import org.hibernate.ejb.event.EJB3PostDeleteEventListener;
import org.hibernate.ejb.event.EJB3PostInsertEventListener;
import org.hibernate.ejb.event.EJB3PostLoadEventListener;
import org.hibernate.ejb.event.EJB3PostUpdateEventListener;
import org.hibernate.ejb.event.EJB3SaveEventListener;
import org.hibernate.ejb.event.EJB3SaveOrUpdateEventListener;
import org.hibernate.ejb.event.EntityCallbackHandler;
import org.hibernate.event.AutoFlushEventListener;
import org.hibernate.event.DeleteEventListener;
import org.hibernate.event.EventListeners;
import org.hibernate.event.FlushEntityEventListener;
import org.hibernate.event.FlushEventListener;
import org.hibernate.event.MergeEventListener;
import org.hibernate.event.PersistEventListener;
import org.hibernate.event.PostDeleteEventListener;
import org.hibernate.event.PostInsertEventListener;
import org.hibernate.event.PostLoadEventListener;
import org.hibernate.event.PostUpdateEventListener;
import org.hibernate.event.PreDeleteEventListener;
import org.hibernate.event.PreInsertEventListener;
import org.hibernate.event.PreLoadEventListener;
import org.hibernate.event.PreUpdateEventListener;
import org.hibernate.event.SaveOrUpdateEventListener;
import org.hibernate.event.def.DefaultPreLoadEventListener;
import org.hibernate.event.def.DefaultPostLoadEventListener;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.secure.JACCPreDeleteEventListener;
import org.hibernate.secure.JACCPreInsertEventListener;
import org.hibernate.secure.JACCPreLoadEventListener;
import org.hibernate.secure.JACCPreUpdateEventListener;
import org.hibernate.secure.JACCSecurityListener;

/**
* @author Emmanuel Bernard
*/
public class EventListenerConfigurator {
  private static final Object[] READER_METHOD_ARGS = new Object[0];

  private Ejb3Configuration configuration;
  private boolean isSecurity;

  public EventListenerConfigurator(Ejb3Configuration configuration) {
    this.configuration = configuration;
    EventListeners listenerConfig = configuration.getEventListeners();

    //Action event
    //EJB3-specific ops listeners
    listenerConfig.setFlushEventListeners( new FlushEventListener[] { EJB3FlushEventListener.INSTANCE } );
    //EJB3-specific ops listeners
    listenerConfig.setAutoFlushEventListeners( new AutoFlushEventListener[] { EJB3AutoFlushEventListener.INSTANCE } );
    listenerConfig.setDeleteEventListeners( new DeleteEventListener[] { new EJB3DeleteEventListener() } );
    listenerConfig.setFlushEntityEventListeners(
        new FlushEntityEventListener[] { new EJB3FlushEntityEventListener() }
    );
    listenerConfig.setMergeEventListeners( new MergeEventListener[] { new EJB3MergeEventListener() } );
    listenerConfig.setPersistEventListeners( new PersistEventListener[] { new EJB3PersistEventListener() } );
    listenerConfig.setPersistOnFlushEventListeners(
        new PersistEventListener[] { new EJB3PersistOnFlushEventListener() }
    );
    listenerConfig.setSaveEventListeners( new SaveOrUpdateEventListener[] { new EJB3SaveEventListener() } );
    listenerConfig.setSaveOrUpdateEventListeners(
        new SaveOrUpdateEventListener[] { new EJB3SaveOrUpdateEventListener() }
    );

    //Pre events
    listenerConfig.setPreInsertEventListeners(
        new PreInsertEventListener[] {
            new JACCPreInsertEventListener(),
        }
    );
    listenerConfig.setPreUpdateEventListeners(
        new PreUpdateEventListener[] {
            new JACCPreUpdateEventListener(),
        }
    );
    listenerConfig.setPreDeleteEventListeners(
        new PreDeleteEventListener[] {
            new JACCPreDeleteEventListener()
        }
    );

    //Add the default Hibernate Core PreLoadEventListener
    //TODO shouldn't we read the value from getPreLoadEventListeners and add JACC?
    //probably a better thing to do as it allows cfg.xml config but this is a big change and need more thoughts
    listenerConfig.setPreLoadEventListeners(
        new PreLoadEventListener[] {
            new DefaultPreLoadEventListener(),
            new JACCPreLoadEventListener()
        }
    );

    //post events
    listenerConfig.setPostDeleteEventListeners(
        new PostDeleteEventListener[] { new EJB3PostDeleteEventListener() }
    );
    listenerConfig.setPostInsertEventListeners(
        new PostInsertEventListener[] { new EJB3PostInsertEventListener() }
    );
    //Add the default Hibernate Core PostLoadEventListener
    //TODO shouldn't we read the value from getPostLoadEventListeners
    //probably a better thing to do as it allows cfg.xml config but this is a big change and need more thoughts
    listenerConfig.setPostLoadEventListeners(
        new PostLoadEventListener[] { new EJB3PostLoadEventListener(), new DefaultPostLoadEventListener() }
    );
    listenerConfig.setPostUpdateEventListeners(
        new PostUpdateEventListener[] { new EJB3PostUpdateEventListener() }
    );
  }

  public void setProperties(Properties properties) {
    if ( properties.containsKey( HibernatePersistence.JACC_ENABLED ) ) {
      isSecurity = true;
    }
    //override events if needed
    Enumeration<?> enumeration = properties.propertyNames();
    while ( enumeration.hasMoreElements() ) {
      String name = (String) enumeration.nextElement();
      if ( name.startsWith( HibernatePersistence.EVENT_LISTENER_PREFIX ) ) {
        String type = name.substring( HibernatePersistence.EVENT_LISTENER_PREFIX.length() + 1 );
        StringTokenizer st = new StringTokenizer( properties.getProperty( name ), " ,", false );
        List<String> listeners = new ArrayList<String>();
        while ( st.hasMoreElements() ) {
          listeners.add( (String) st.nextElement() );
        }
        configuration.setListeners( type, listeners.toArray( new String[listeners.size()] ) );
      }
    }
  }

  public void configure() {
    //TODO exclude pure hbm file classes?
    //TODO move it to each event listener initialize()?
    EntityCallbackHandler callbackHandler = new EntityCallbackHandler();
    configuration.buildMappings(); //needed to get all the classes
    Iterator classes = configuration.getClassMappings();
    ReflectionManager reflectionManager = configuration.getHibernateConfiguration().getReflectionManager();
    while ( classes.hasNext() ) {
      PersistentClass clazz = (PersistentClass) classes.next();
      if ( clazz.getClassName() != null ) {
        //we can have non java class persisted by hibernate
        try {
          callbackHandler.add( reflectionManager.classForName( clazz.getClassName(), this.getClass() ), reflectionManager );
        }
        catch (ClassNotFoundException e) {
          throw new MappingException( "entity class not found: " + clazz.getNodeName(), e );
        }
      }
    }

    EventListeners listenerConfig = configuration.getEventListeners();

    BeanInfo beanInfo = null;
    try {
      beanInfo = Introspector.getBeanInfo( listenerConfig.getClass(), Object.class );
      PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
      try {
        for (int i = 0, max = pds.length; i < max; i++) {
          final Object listeners = pds[i].getReadMethod().invoke( listenerConfig, READER_METHOD_ARGS );
          if ( listeners == null ) {
            throw new HibernateException( "Listener [" + pds[i].getName() + "] was null" );
          }
          if ( listeners instanceof Object[] ) {
            int securityListenersNbr = 0;
            Object[] listenersArray = (Object[]) listeners;
            for (Object listener : listenersArray) {
              if ( listener != null && listener instanceof CallbackHandlerConsumer ) {
                ( (CallbackHandlerConsumer) listener ).setCallbackHandler( callbackHandler );
              }
              if ( listener != null && listener instanceof JACCSecurityListener ) {
                if ( !isSecurity ) {
                  securityListenersNbr++;
                }
              }
            }
            if ( !isSecurity ) {
              Class clazz = pds[i].getReadMethod().getReturnType().getComponentType();
              Object newArray = Array.newInstance( clazz, listenersArray.length - securityListenersNbr );
              int index = 0;
              for (Object listener : listenersArray) {
                if ( !( listener != null && listener instanceof JACCSecurityListener ) ) {
                  Array.set( newArray, index++, listener );
                }
              }
              pds[i].getWriteMethod().invoke( listenerConfig, newArray );
            }
          }
        }
      }
      catch (HibernateException e) {
        throw e;
      }
      catch (Throwable t) {
        throw new HibernateException( "Unable to validate listener config", t );
      }
    }
    catch (Exception t) {
      throw new HibernateException( "Unable to copy listeners", t );
    }
    finally {
      if ( beanInfo != null ) {
        // release the jdk internal caches everytime to ensure this
        // plays nicely with destroyable class-loaders
        Introspector.flushFromCaches( getClass() );
      }
    }
  }
}
TOP

Related Classes of org.hibernate.ejb.EventListenerConfigurator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.