/* * Copyright 2004-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.compass.gps.device.jpa.lifecycle; import java.util.ArrayList; import javax.persistence.EntityManagerFactory; import org.compass.gps.device.jpa.AbstractDeviceJpaEntityListener; import org.compass.gps.device.jpa.JpaGpsDevice; import org.compass.gps.device.jpa.JpaGpsDeviceException; import org.hibernate.ejb.HibernateEntityManagerFactory; import org.hibernate.event.EventListeners; import org.hibernate.event.PostDeleteEvent; import org.hibernate.event.PostDeleteEventListener; import org.hibernate.event.PostInsertEvent; import org.hibernate.event.PostInsertEventListener; import org.hibernate.event.PostUpdateEvent; import org.hibernate.event.PostUpdateEventListener; import org.hibernate.impl.SessionFactoryImpl; /** * Injects lifecycle listeners directly into Hibernate for mirroring operations. * * <p>By default, registers with plain insert/update/delete listeners, which will be triggered * by Hibernate before committing (and up to Hibernate flushing logic). Also allows to be created * with setting the <code>registerPostCommitListeneres</code> to <code>true</code> which will cause * the insert/update/delete listeneres to be registered as post commit events. * * @author kimchy */ public class HibernateJpaEntityLifecycleInjector implements JpaEntityLifecycleInjector { public static class HibernateEventListener extends AbstractDeviceJpaEntityListener implements PostInsertEventListener, PostUpdateEventListener, PostDeleteEventListener { private JpaGpsDevice device; public HibernateEventListener(JpaGpsDevice device) { this.device = device; } protected JpaGpsDevice getDevice() { return this.device; } public void onPostInsert(PostInsertEvent postInsertEvent) { postPersist(postInsertEvent.getEntity()); } public void onPostUpdate(PostUpdateEvent postUpdateEvent) { postUpdate(postUpdateEvent.getEntity()); } public void onPostDelete(PostDeleteEvent postDeleteEvent) { postRemove(postDeleteEvent.getEntity()); } } protected final boolean registerPostCommitListeneres; public HibernateJpaEntityLifecycleInjector() { this(false); } /** * Creates a new lifecycle injector. Allows to control if the insert/update/delete * even listeners will be registered with post commit listeres (flag it <code>true</code>) * or with plain post events (triggered based on Hibrenate flushing logic). * * @param registerPostCommitListeneres <code>true</code> if post commit listeners will be * registered. <code>false</code> for plain listeners. */ public HibernateJpaEntityLifecycleInjector(boolean registerPostCommitListeneres) { this.registerPostCommitListeneres = registerPostCommitListeneres; } public boolean requireRefresh() { return false; } public void injectLifecycle(EntityManagerFactory entityManagerFactory, JpaGpsDevice device) throws JpaGpsDeviceException { HibernateEntityManagerFactory hibernateEntityManagerFactory = (HibernateEntityManagerFactory) entityManagerFactory; SessionFactoryImpl sessionFactory = (SessionFactoryImpl) hibernateEntityManagerFactory.getSessionFactory(); EventListeners eventListeners = sessionFactory.getEventListeners(); Object hibernateEventListener = doCreateListener(device); if (hibernateEventListener instanceof PostInsertEventListener) { PostInsertEventListener[] postInsertEventListeners; if (registerPostCommitListeneres) { postInsertEventListeners = eventListeners.getPostCommitInsertEventListeners(); } else { postInsertEventListeners = eventListeners.getPostInsertEventListeners(); } PostInsertEventListener[] tempPostInsertEventListeners = new PostInsertEventListener[postInsertEventListeners.length + 1]; System.arraycopy(postInsertEventListeners, 0, tempPostInsertEventListeners, 0, postInsertEventListeners.length); tempPostInsertEventListeners[postInsertEventListeners.length] = (PostInsertEventListener) hibernateEventListener; if (registerPostCommitListeneres) { eventListeners.setPostCommitInsertEventListeners(tempPostInsertEventListeners); } else { eventListeners.setPostInsertEventListeners(tempPostInsertEventListeners); } } if (hibernateEventListener instanceof PostUpdateEventListener) { PostUpdateEventListener[] postUpdateEventListeners; if (registerPostCommitListeneres) { postUpdateEventListeners = eventListeners.getPostCommitUpdateEventListeners(); } else { postUpdateEventListeners = eventListeners.getPostUpdateEventListeners(); } PostUpdateEventListener[] tempPostUpdateEventListeners = new PostUpdateEventListener[postUpdateEventListeners.length + 1]; System.arraycopy(postUpdateEventListeners, 0, tempPostUpdateEventListeners, 0, postUpdateEventListeners.length); tempPostUpdateEventListeners[postUpdateEventListeners.length] = (PostUpdateEventListener) hibernateEventListener; if (registerPostCommitListeneres) { eventListeners.setPostCommitUpdateEventListeners(tempPostUpdateEventListeners); } else { eventListeners.setPostUpdateEventListeners(tempPostUpdateEventListeners); } } if (hibernateEventListener instanceof PostDeleteEventListener) { PostDeleteEventListener[] postDeleteEventListeners; if (registerPostCommitListeneres) { postDeleteEventListeners = eventListeners.getPostCommitDeleteEventListeners(); } else { postDeleteEventListeners = eventListeners.getPostDeleteEventListeners(); } PostDeleteEventListener[] tempPostDeleteEventListeners = new PostDeleteEventListener[postDeleteEventListeners.length + 1]; System.arraycopy(postDeleteEventListeners, 0, tempPostDeleteEventListeners, 0, postDeleteEventListeners.length); tempPostDeleteEventListeners[postDeleteEventListeners.length] = (PostDeleteEventListener) hibernateEventListener; if (registerPostCommitListeneres) { eventListeners.setPostCommitDeleteEventListeners(tempPostDeleteEventListeners); } else { eventListeners.setPostDeleteEventListeners(tempPostDeleteEventListeners); } } } public void removeLifecycle(EntityManagerFactory entityManagerFactory, JpaGpsDevice device) throws JpaGpsDeviceException { HibernateEntityManagerFactory hibernateEntityManagerFactory = (HibernateEntityManagerFactory) entityManagerFactory; SessionFactoryImpl sessionFactory = (SessionFactoryImpl) hibernateEntityManagerFactory.getSessionFactory(); EventListeners eventListeners = sessionFactory.getEventListeners(); PostInsertEventListener[] postInsertEventListeners; if (registerPostCommitListeneres) { postInsertEventListeners = eventListeners.getPostCommitInsertEventListeners(); } else { postInsertEventListeners = eventListeners.getPostInsertEventListeners(); } ArrayList<PostInsertEventListener> tempPostInsertEventListeners = new ArrayList<PostInsertEventListener>(); for (PostInsertEventListener postInsertEventListener : postInsertEventListeners) { if (!(postInsertEventListener instanceof HibernateEventListener)) { tempPostInsertEventListeners.add(postInsertEventListener); } } if (registerPostCommitListeneres) { eventListeners.setPostCommitInsertEventListeners(tempPostInsertEventListeners.toArray(new PostInsertEventListener[tempPostInsertEventListeners.size()])); } else { eventListeners.setPostInsertEventListeners(tempPostInsertEventListeners.toArray(new PostInsertEventListener[tempPostInsertEventListeners.size()])); } PostUpdateEventListener[] postUpdateEventListeners; if (registerPostCommitListeneres) { postUpdateEventListeners = eventListeners.getPostCommitUpdateEventListeners(); } else { postUpdateEventListeners = eventListeners.getPostUpdateEventListeners(); } ArrayList<PostUpdateEventListener> tempPostUpdateEventListeners = new ArrayList<PostUpdateEventListener>(); for (PostUpdateEventListener postUpdateEventListener : postUpdateEventListeners) { if (!(postUpdateEventListener instanceof HibernateEventListener)) { tempPostUpdateEventListeners.add(postUpdateEventListener); } } if (registerPostCommitListeneres) { eventListeners.setPostCommitUpdateEventListeners(tempPostUpdateEventListeners.toArray(new PostUpdateEventListener[tempPostUpdateEventListeners.size()])); } else { eventListeners.setPostUpdateEventListeners(tempPostUpdateEventListeners.toArray(new PostUpdateEventListener[tempPostUpdateEventListeners.size()])); } PostDeleteEventListener[] postDeleteEventListeners; if (registerPostCommitListeneres) { postDeleteEventListeners = eventListeners.getPostCommitDeleteEventListeners(); } else { postDeleteEventListeners = eventListeners.getPostDeleteEventListeners(); } ArrayList<PostDeleteEventListener> tempPostDeleteEventListeners = new ArrayList<PostDeleteEventListener>(); for (PostDeleteEventListener postDeleteEventListener : postDeleteEventListeners) { if (!(postDeleteEventListener instanceof HibernateEventListener)) { tempPostDeleteEventListeners.add(postDeleteEventListener); } } if (registerPostCommitListeneres) { eventListeners.setPostCommitDeleteEventListeners(tempPostDeleteEventListeners.toArray(new PostDeleteEventListener[tempPostDeleteEventListeners.size()])); } else { eventListeners.setPostDeleteEventListeners(tempPostDeleteEventListeners.toArray(new PostDeleteEventListener[tempPostDeleteEventListeners.size()])); } } protected Object doCreateListener(JpaGpsDevice device) { return new HibernateEventListener(device); } }