org.hibernate.jpa.event.internal.jpa.ListenerFactoryBeanManagerDelayedImpl Maven / Gradle / Ivy
/*
* 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.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. This implementation
* delayes access to the CDI BeanManager until first need.
*
* @author Steve Ebersole
*/
@SuppressWarnings("unused")
public class ListenerFactoryBeanManagerDelayedImpl implements ListenerFactory {
private static final Logger log = Logger.getLogger( ListenerFactoryBeanManagerDelayedImpl.class );
private final BeanManager beanManager;
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 ListenerFactoryBeanManagerDelayedImpl fromBeanManagerReference(Object reference) {
if ( !BeanManager.class.isInstance( reference ) ) {
throw new IllegalArgumentException(
"Expecting BeanManager reference that implements CDI BeanManager contract : " +
reference
);
}
return new ListenerFactoryBeanManagerDelayedImpl( (BeanManager) reference );
}
public ListenerFactoryBeanManagerDelayedImpl(BeanManager beanManager) {
this.beanManager = beanManager;
log.debugf( "Delayed 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();
}
private 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;
log.debugf( "Delayed CDI listener built : " + listenerClass );
}
public void initialize() {
log.debug( "Initializing delayed CDI listener on first use : " + listenerClass );
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 ) {
initialize();
}
return listenerInstance;
}
public void release() {
if ( !initialized ) {
log.debug( "Skipping release for CDI listener [" + listenerClass + "] as it was not initialized" );
return;
}
log.debug( "Releasing CDI listener : " + listenerClass );
injectionTarget.preDestroy( listenerInstance );
injectionTarget.dispose( listenerInstance );
creationalContext.release();
}
}
}