All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hibernate.jpa.event.internal.jpa.ListenerFactoryBeanManagerExtendedImpl Maven / Gradle / Ivy

There is a newer version: 7.0.0.Alpha1
Show newest version
/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
 * See the lgpl.txt file in the root directory or .
 */
package org.hibernate.jpa.event.internal.jpa;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.InjectionTarget;

import org.hibernate.HibernateException;
import org.hibernate.jpa.event.spi.jpa.ExtendedBeanManager;
import org.hibernate.jpa.event.spi.jpa.Listener;
import org.hibernate.jpa.event.spi.jpa.ListenerFactory;

import org.jboss.logging.Logger;

/**
 * CDI-based implementation of the ListenerFactory contract.  Further, this
 * implementation leverages the ExtendedBeanManager contract to delay CDI calls.
 *
 * @author Steve Ebersole
 */
@SuppressWarnings("unused")
public class ListenerFactoryBeanManagerExtendedImpl implements ListenerFactory, ExtendedBeanManager.LifecycleListener {
	private static final Logger log = Logger.getLogger( ListenerFactoryBeanManagerExtendedImpl.class );

	private final Map listenerMap = new ConcurrentHashMap();

	/**
	 * Used via reflection from JpaIntegrator, the intent being to isolate CDI dependency
	 * to just this class and its delegates in the case that a BeanManager is passed.
	 *
	 * @param reference The BeanManager reference
	 *
	 * @return A instantiated ListenerFactoryBeanManagerImpl
	 */
	@SuppressWarnings("unused")
	public static ListenerFactoryBeanManagerExtendedImpl fromBeanManagerReference(Object reference) {
		if ( !ExtendedBeanManager.class.isInstance( reference ) ) {
			throw new IllegalArgumentException(
					"Expecting BeanManager reference that implements optional ExtendedBeanManager contract : " +
							reference
			);
		}
		return new ListenerFactoryBeanManagerExtendedImpl( (ExtendedBeanManager) reference );
	}

	public ListenerFactoryBeanManagerExtendedImpl(ExtendedBeanManager beanManager) {
		beanManager.registerLifecycleListener( this );
		log.debugf( "ExtendedBeanManager access requested to CDI BeanManager : " + beanManager );
	}

	@Override
	@SuppressWarnings("unchecked")
	public  Listener buildListener(Class listenerClass) {
		ListenerImpl listenerImpl = listenerMap.get( listenerClass );
		if ( listenerImpl == null ) {
			listenerImpl = new ListenerImpl( listenerClass );
			listenerMap.put( listenerClass, listenerImpl );
		}
		return (Listener) listenerImpl;
	}

	@Override
	public void release() {
		for ( ListenerImpl listenerImpl : listenerMap.values() ) {
			listenerImpl.release();
		}
		listenerMap.clear();
	}

	@Override
	public void beanManagerInitialized(BeanManager beanManager) {
		for ( ListenerImpl listenerImpl : listenerMap.values() ) {
			listenerImpl.initialize( beanManager );
		}
	}

	private static class ListenerImpl implements Listener {
		private final Class listenerClass;

		private boolean initialized = false;

		private InjectionTarget injectionTarget;
		private CreationalContext creationalContext;
		private T listenerInstance;

		private ListenerImpl(Class listenerClass) {
			this.listenerClass = listenerClass;
		}

		public void initialize(BeanManager beanManager) {
			AnnotatedType annotatedType = beanManager.createAnnotatedType( listenerClass );
			this.injectionTarget = beanManager.createInjectionTarget( annotatedType );
			this.creationalContext = beanManager.createCreationalContext( null );

			this.listenerInstance = injectionTarget.produce( creationalContext );
			injectionTarget.inject( this.listenerInstance, creationalContext );

			injectionTarget.postConstruct( this.listenerInstance );

			this.initialized = true;
		}

		@Override
		public T getListener() {
			if ( !initialized ) {
				throw new HibernateException( "CDI not initialized as expected" );
			}
			return listenerInstance;
		}

		public void release() {
			if ( !initialized ) {
				// log
				return;
			}

			injectionTarget.preDestroy( listenerInstance );
			injectionTarget.dispose( listenerInstance );
			creationalContext.release();
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy