/*
* 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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.event.collection.detached;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.SessionFactory;
import org.hibernate.engine.spi.CollectionEntry;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.event.internal.DefaultInitializeCollectionEventListener;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.AbstractCollectionEvent;
import org.hibernate.event.spi.EventType;
import org.hibernate.event.spi.InitializeCollectionEvent;
import org.hibernate.event.spi.PostCollectionRecreateEvent;
import org.hibernate.event.spi.PostCollectionRecreateEventListener;
import org.hibernate.event.spi.PostCollectionRemoveEvent;
import org.hibernate.event.spi.PostCollectionRemoveEventListener;
import org.hibernate.event.spi.PostCollectionUpdateEvent;
import org.hibernate.event.spi.PostCollectionUpdateEventListener;
import org.hibernate.event.spi.PreCollectionRecreateEvent;
import org.hibernate.event.spi.PreCollectionRecreateEventListener;
import org.hibernate.event.spi.PreCollectionRemoveEvent;
import org.hibernate.event.spi.PreCollectionRemoveEventListener;
import org.hibernate.event.spi.PreCollectionUpdateEvent;
import org.hibernate.event.spi.PreCollectionUpdateEventListener;
import org.jboss.logging.Logger;
/**
* Support listeners for Test HHH-6361: Collection events may contain wrong
* stored snapshot after merging a detached entity into the persistencecontext.
*
* @author Erik-Berndt Scheper
*/
public class MultipleCollectionListeners {
private final Logger log = Logger.getLogger(MultipleCollectionListeners.class);
public interface Listener extends Serializable {
void addEvent(AbstractCollectionEvent event, Listener listener);
}
public static abstract class AbstractListener implements Listener {
private final MultipleCollectionListeners listeners;
protected AbstractListener(MultipleCollectionListeners listeners) {
this.listeners = listeners;
}
public void addEvent(AbstractCollectionEvent event, Listener listener) {
listeners.addEvent(event, listener);
}
}
public static class InitializeCollectionListener extends
DefaultInitializeCollectionEventListener implements Listener {
private final MultipleCollectionListeners listeners;
private InitializeCollectionListener(
MultipleCollectionListeners listeners) {
this.listeners = listeners;
}
public void onInitializeCollection(InitializeCollectionEvent event) {
super.onInitializeCollection(event);
addEvent(event, this);
}
public void addEvent(AbstractCollectionEvent event, Listener listener) {
listeners.addEvent(event, listener);
}
}
public static class PreCollectionRecreateListener extends AbstractListener
implements PreCollectionRecreateEventListener {
private PreCollectionRecreateListener(
MultipleCollectionListeners listeners) {
super(listeners);
}
public void onPreRecreateCollection(PreCollectionRecreateEvent event) {
addEvent(event, this);
}
}
public static class PostCollectionRecreateListener extends AbstractListener
implements PostCollectionRecreateEventListener {
private PostCollectionRecreateListener(
MultipleCollectionListeners listeners) {
super(listeners);
}
public void onPostRecreateCollection(PostCollectionRecreateEvent event) {
addEvent(event, this);
}
}
public static class PreCollectionRemoveListener extends AbstractListener
implements PreCollectionRemoveEventListener {
private PreCollectionRemoveListener(
MultipleCollectionListeners listeners) {
super(listeners);
}
public void onPreRemoveCollection(PreCollectionRemoveEvent event) {
addEvent(event, this);
}
}
public static class PostCollectionRemoveListener extends AbstractListener
implements PostCollectionRemoveEventListener {
private PostCollectionRemoveListener(
MultipleCollectionListeners listeners) {
super(listeners);
}
public void onPostRemoveCollection(PostCollectionRemoveEvent event) {
addEvent(event, this);
}
}
public static class PreCollectionUpdateListener extends AbstractListener
implements PreCollectionUpdateEventListener {
private PreCollectionUpdateListener(
MultipleCollectionListeners listeners) {
super(listeners);
}
public void onPreUpdateCollection(PreCollectionUpdateEvent event) {
addEvent(event, this);
}
}
public static class PostCollectionUpdateListener extends AbstractListener
implements PostCollectionUpdateEventListener {
private PostCollectionUpdateListener(
MultipleCollectionListeners listeners) {
super(listeners);
}
public void onPostUpdateCollection(PostCollectionUpdateEvent event) {
addEvent(event, this);
}
}
private final PreCollectionRecreateListener preCollectionRecreateListener;
private final InitializeCollectionListener initializeCollectionListener;
private final PreCollectionRemoveListener preCollectionRemoveListener;
private final PreCollectionUpdateListener preCollectionUpdateListener;
private final PostCollectionRecreateListener postCollectionRecreateListener;
private final PostCollectionRemoveListener postCollectionRemoveListener;
private final PostCollectionUpdateListener postCollectionUpdateListener;
private List<Listener> listenersCalled = new ArrayList<Listener>();
private List<AbstractCollectionEvent> events = new ArrayList<AbstractCollectionEvent>();
private List<Serializable> snapshots = new ArrayList<Serializable>();
public MultipleCollectionListeners(SessionFactory sf) {
preCollectionRecreateListener = new PreCollectionRecreateListener(this);
initializeCollectionListener = new InitializeCollectionListener(this);
preCollectionRemoveListener = new PreCollectionRemoveListener(this);
preCollectionUpdateListener = new PreCollectionUpdateListener(this);
postCollectionRecreateListener = new PostCollectionRecreateListener(
this);
postCollectionRemoveListener = new PostCollectionRemoveListener(this);
postCollectionUpdateListener = new PostCollectionUpdateListener(this);
EventListenerRegistry registry = ( (SessionFactoryImplementor) sf ).getServiceRegistry().getService( EventListenerRegistry.class );
registry.setListeners( EventType.INIT_COLLECTION, initializeCollectionListener );
registry.setListeners( EventType.PRE_COLLECTION_RECREATE, preCollectionRecreateListener );
registry.setListeners( EventType.POST_COLLECTION_RECREATE, postCollectionRecreateListener );
registry.setListeners( EventType.PRE_COLLECTION_REMOVE, preCollectionRemoveListener );
registry.setListeners( EventType.POST_COLLECTION_REMOVE, postCollectionRemoveListener );
registry.setListeners( EventType.PRE_COLLECTION_UPDATE, preCollectionUpdateListener );
registry.setListeners( EventType.POST_COLLECTION_UPDATE, postCollectionUpdateListener );
}
public void addEvent(AbstractCollectionEvent event, Listener listener) {
CollectionEntry collectionEntry = event.getSession()
.getPersistenceContext()
.getCollectionEntry(event.getCollection());
Serializable snapshot = collectionEntry.getSnapshot();
log.debug("add Event: " + event.getClass() + "; listener = "
+ listener.getClass() + "; snapshot = " + snapshot);
listenersCalled.add(listener);
events.add(event);
snapshots.add(snapshot);
}
public List<Listener> getListenersCalled() {
return listenersCalled;
}
public List<AbstractCollectionEvent> getEvents() {
return events;
}
public List<Serializable> getSnapshots() {
return snapshots;
}
public void clear() {
listenersCalled.clear();
events.clear();
snapshots.clear();
}
public PreCollectionRecreateListener getPreCollectionRecreateListener() {
return preCollectionRecreateListener;
}
public InitializeCollectionListener getInitializeCollectionListener() {
return initializeCollectionListener;
}
public PreCollectionRemoveListener getPreCollectionRemoveListener() {
return preCollectionRemoveListener;
}
public PreCollectionUpdateListener getPreCollectionUpdateListener() {
return preCollectionUpdateListener;
}
public PostCollectionRecreateListener getPostCollectionRecreateListener() {
return postCollectionRecreateListener;
}
public PostCollectionRemoveListener getPostCollectionRemoveListener() {
return postCollectionRemoveListener;
}
public PostCollectionUpdateListener getPostCollectionUpdateListener() {
return postCollectionUpdateListener;
}
}