/* * 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; } }