Save This Page
Home » hibernate-entity-src-20081106 » org.hibernate » ejb » [javadoc | source]
    1   //$Id: EventListenerConfigurator.java 11251 2007-03-02 08:26:10Z epbernard $
    2   package org.hibernate.ejb;
    3   
    4   import java.beans.BeanInfo;
    5   import java.beans.Introspector;
    6   import java.beans.PropertyDescriptor;
    7   import java.lang.reflect.Array;
    8   import java.util.ArrayList;
    9   import java.util.Enumeration;
   10   import java.util.Iterator;
   11   import java.util.List;
   12   import java.util.Properties;
   13   import java.util.StringTokenizer;
   14   
   15   import org.hibernate.HibernateException;
   16   import org.hibernate.MappingException;
   17   import org.hibernate.ejb.event.CallbackHandlerConsumer;
   18   import org.hibernate.ejb.event.EJB3AutoFlushEventListener;
   19   import org.hibernate.ejb.event.EJB3DeleteEventListener;
   20   import org.hibernate.ejb.event.EJB3FlushEntityEventListener;
   21   import org.hibernate.ejb.event.EJB3FlushEventListener;
   22   import org.hibernate.ejb.event.EJB3MergeEventListener;
   23   import org.hibernate.ejb.event.EJB3PersistEventListener;
   24   import org.hibernate.ejb.event.EJB3PersistOnFlushEventListener;
   25   import org.hibernate.ejb.event.EJB3PostDeleteEventListener;
   26   import org.hibernate.ejb.event.EJB3PostInsertEventListener;
   27   import org.hibernate.ejb.event.EJB3PostLoadEventListener;
   28   import org.hibernate.ejb.event.EJB3PostUpdateEventListener;
   29   import org.hibernate.ejb.event.EJB3SaveEventListener;
   30   import org.hibernate.ejb.event.EJB3SaveOrUpdateEventListener;
   31   import org.hibernate.ejb.event.EntityCallbackHandler;
   32   import org.hibernate.event.AutoFlushEventListener;
   33   import org.hibernate.event.DeleteEventListener;
   34   import org.hibernate.event.EventListeners;
   35   import org.hibernate.event.FlushEntityEventListener;
   36   import org.hibernate.event.FlushEventListener;
   37   import org.hibernate.event.MergeEventListener;
   38   import org.hibernate.event.PersistEventListener;
   39   import org.hibernate.event.PostDeleteEventListener;
   40   import org.hibernate.event.PostInsertEventListener;
   41   import org.hibernate.event.PostLoadEventListener;
   42   import org.hibernate.event.PostUpdateEventListener;
   43   import org.hibernate.event.PreDeleteEventListener;
   44   import org.hibernate.event.PreInsertEventListener;
   45   import org.hibernate.event.PreLoadEventListener;
   46   import org.hibernate.event.PreUpdateEventListener;
   47   import org.hibernate.event.SaveOrUpdateEventListener;
   48   import org.hibernate.mapping.PersistentClass;
   49   import org.hibernate.annotations.common.reflection.ReflectionManager;
   50   import org.hibernate.secure.JACCPreDeleteEventListener;
   51   import org.hibernate.secure.JACCPreInsertEventListener;
   52   import org.hibernate.secure.JACCPreLoadEventListener;
   53   import org.hibernate.secure.JACCPreUpdateEventListener;
   54   import org.hibernate.secure.JACCSecurityListener;
   55   import org.hibernate.validator.event.ValidateEventListener;
   56   
   57   /**
   58    * @author Emmanuel Bernard
   59    */
   60   public class EventListenerConfigurator {
   61   	private static final Object[] READER_METHOD_ARGS = new Object[0];
   62   
   63   	private Ejb3Configuration configuration;
   64   	private boolean isSecurity;
   65   
   66   	public EventListenerConfigurator(Ejb3Configuration configuration) {
   67   		this.configuration = configuration;
   68   		EventListeners listenerConfig = configuration.getEventListeners();
   69   
   70   		//Action event
   71   		//EJB3-specific ops listeners
   72   		listenerConfig.setFlushEventListeners( new FlushEventListener[]{EJB3FlushEventListener.INSTANCE} );
   73   		//EJB3-specific ops listeners
   74   		listenerConfig.setAutoFlushEventListeners( new AutoFlushEventListener[]{EJB3AutoFlushEventListener.INSTANCE} );
   75   		listenerConfig.setDeleteEventListeners( new DeleteEventListener[]{new EJB3DeleteEventListener()} );
   76   		listenerConfig.setFlushEntityEventListeners(
   77   				new FlushEntityEventListener[]{new EJB3FlushEntityEventListener()}
   78   		);
   79   		listenerConfig.setMergeEventListeners( new MergeEventListener[]{new EJB3MergeEventListener()} );
   80   		listenerConfig.setPersistEventListeners( new PersistEventListener[]{new EJB3PersistEventListener()} );
   81   		listenerConfig.setPersistOnFlushEventListeners(
   82   				new PersistEventListener[]{new EJB3PersistOnFlushEventListener()}
   83   		);
   84   		listenerConfig.setSaveEventListeners( new SaveOrUpdateEventListener[]{new EJB3SaveEventListener()} );
   85   		listenerConfig.setSaveOrUpdateEventListeners(
   86   				new SaveOrUpdateEventListener[]{new EJB3SaveOrUpdateEventListener()}
   87   		);
   88   
   89   		//Pre events
   90   		listenerConfig.setPreInsertEventListeners(
   91   				new PreInsertEventListener[]{
   92   						new JACCPreInsertEventListener(),
   93   				}
   94   		);
   95   		listenerConfig.setPreUpdateEventListeners(
   96   				new PreUpdateEventListener[]{
   97   						new JACCPreUpdateEventListener(),
   98   				}
   99   		);
  100   		listenerConfig.setPreDeleteEventListeners(
  101   				new PreDeleteEventListener[]{
  102   						new JACCPreDeleteEventListener()
  103   				}
  104   		);
  105   		listenerConfig.setPreLoadEventListeners(
  106   				new PreLoadEventListener[]{
  107   						new JACCPreLoadEventListener()
  108   				}
  109   		);
  110   
  111   		//post events
  112   		listenerConfig.setPostDeleteEventListeners(
  113   				new PostDeleteEventListener[]{new EJB3PostDeleteEventListener()}
  114   		);
  115   		listenerConfig.setPostInsertEventListeners(
  116   				new PostInsertEventListener[]{new EJB3PostInsertEventListener()}
  117   		);
  118   		listenerConfig.setPostLoadEventListeners(
  119   				new PostLoadEventListener[]{new EJB3PostLoadEventListener()}
  120   		);
  121   		listenerConfig.setPostUpdateEventListeners(
  122   				new PostUpdateEventListener[]{new EJB3PostUpdateEventListener()}
  123   		);
  124   	}
  125   
  126   	public void setProperties(Properties properties) {
  127   		if ( properties.containsKey( HibernatePersistence.JACC_ENABLED ) ) {
  128   			isSecurity = true;
  129   		}
  130   		//override events if needed
  131   		Enumeration<?> enumeration = properties.propertyNames();
  132   		while ( enumeration.hasMoreElements() ) {
  133   			String name = (String) enumeration.nextElement();
  134   			if ( name.startsWith( HibernatePersistence.EVENT_LISTENER_PREFIX ) ) {
  135   				String type = name.substring( HibernatePersistence.EVENT_LISTENER_PREFIX.length() + 1 );
  136   				StringTokenizer st = new StringTokenizer( properties.getProperty( name ), " ,", false );
  137   				List<String> listeners = new ArrayList<String>();
  138   				while ( st.hasMoreElements() ) {
  139   					listeners.add( (String) st.nextElement() );
  140   				}
  141   				configuration.setListeners( type, listeners.toArray( new String[ listeners.size() ] ) );
  142   			}
  143   		}
  144   	}
  145   
  146   	public void configure() {
  147   		//TODO exclude pure hbm file classes?
  148   		//TODO move it to each event listener initialize()?
  149   		EntityCallbackHandler callbackHandler = new EntityCallbackHandler();
  150   		configuration.buildMappings(); //needed to get all the classes
  151   		Iterator classes = configuration.getClassMappings();
  152   		ReflectionManager reflectionManager = configuration.getHibernateConfiguration().getReflectionManager();
  153   		while ( classes.hasNext() ) {
  154   			PersistentClass clazz = (PersistentClass) classes.next();
  155   			if ( clazz.getClassName() != null ) {
  156   				//we can have non java class persisted by hibernate
  157   				try {
  158   					callbackHandler.add( reflectionManager.classForName( clazz.getClassName(), this.getClass() ), reflectionManager );
  159   				}
  160   				catch (ClassNotFoundException e) {
  161   					throw new MappingException("entity class not found: " + clazz.getNodeName(), e);
  162   				}
  163   			}
  164   		}
  165   
  166   		EventListeners listenerConfig = configuration.getEventListeners();
  167   
  168   		BeanInfo beanInfo = null;
  169   		try {
  170   			beanInfo = Introspector.getBeanInfo( listenerConfig.getClass(), Object.class );
  171   			PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
  172   			try {
  173   				for ( int i = 0, max = pds.length; i < max ; i++ ) {
  174   					final Object listeners = pds[i].getReadMethod().invoke( listenerConfig, READER_METHOD_ARGS );
  175   					if ( listeners == null ) {
  176   						throw new HibernateException( "Listener [" + pds[i].getName() + "] was null" );
  177   					}
  178   					if ( listeners instanceof Object[] ) {
  179   						int securityListenersNbr = 0;
  180   						Object[] listenersArray = (Object[]) listeners;
  181   						for ( Object listener : listenersArray ) {
  182   							if ( listener != null && listener instanceof CallbackHandlerConsumer ) {
  183   								( (CallbackHandlerConsumer) listener ).setCallbackHandler( callbackHandler );
  184   							}
  185   							if ( listener != null && listener instanceof JACCSecurityListener ) {
  186   								if ( !isSecurity ) {
  187   									securityListenersNbr++;
  188   								}
  189   							}
  190   						}
  191   						if ( !isSecurity ) {
  192   							Class clazz = pds[i].getReadMethod().getReturnType().getComponentType();
  193   							Object newArray = Array.newInstance( clazz, listenersArray.length - securityListenersNbr );
  194   							int index = 0;
  195   							for ( Object listener : listenersArray ) {
  196   								if ( ! ( listener != null && listener instanceof JACCSecurityListener ) ) {
  197   									Array.set( newArray, index++, listener );
  198   								}
  199   							}
  200   							pds[i].getWriteMethod().invoke( listenerConfig, newArray );
  201   						}
  202   					}
  203   				}
  204   			}
  205   			catch (HibernateException e) {
  206   				throw e;
  207   			}
  208   			catch (Throwable t) {
  209   				throw new HibernateException( "Unable to validate listener config", t );
  210   			}
  211   		}
  212   		catch (Exception t) {
  213   			throw new HibernateException( "Unable to copy listeners", t );
  214   		}
  215   		finally {
  216   			if ( beanInfo != null ) {
  217   				// release the jdk internal caches everytime to ensure this
  218   				// plays nicely with destroyable class-loaders
  219   				Introspector.flushFromCaches( getClass() );
  220   			}
  221   		}
  222   	}
  223   }

Save This Page
Home » hibernate-entity-src-20081106 » org.hibernate » ejb » [javadoc | source]