diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/event/AbstractLifecycleListener.java b/openjpa-kernel/src/main/java/org/apache/openjpa/event/AbstractLifecycleListener.java index 01ff450c8..87778962a 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/event/AbstractLifecycleListener.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/event/AbstractLifecycleListener.java @@ -34,6 +34,10 @@ public abstract class AbstractLifecycleListener protected void eventOccurred(LifecycleEvent event) { } + public void beforePersist(LifecycleEvent event) { + eventOccurred(event); + } + public void afterPersist(LifecycleEvent event) { eventOccurred(event); } @@ -81,4 +85,24 @@ public abstract class AbstractLifecycleListener public void afterDirtyFlushed(LifecycleEvent event) { eventOccurred(event); } + + public void afterRefresh(LifecycleEvent event) { + eventOccurred(event); + } + + public void beforeDetach(LifecycleEvent event) { + eventOccurred(event); + } + + public void afterDetach(LifecycleEvent event) { + eventOccurred(event); + } + + public void beforeAttach(LifecycleEvent event) { + eventOccurred(event); + } + + public void afterAttach(LifecycleEvent event) { + eventOccurred(event); + } } diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/event/LifecycleEventManager.java b/openjpa-kernel/src/main/java/org/apache/openjpa/event/LifecycleEventManager.java index 96314ec78..674ad7e40 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/event/LifecycleEventManager.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/event/LifecycleEventManager.java @@ -131,75 +131,68 @@ public class LifecycleEventManager * Return whether there are listeners or callbacks for the given source. */ public boolean hasPersistListeners(Object source, ClassMetaData meta) { - return hasCallbacks(source, meta, LifecycleEvent.BEFORE_PERSIST) - || hasCallbacks(source, meta, LifecycleEvent.AFTER_PERSIST) - || hasListeners(source, meta, LifecycleEvent.AFTER_PERSIST); + return hasHandlers(source, meta, LifecycleEvent.BEFORE_PERSIST) + || hasHandlers(source, meta, LifecycleEvent.AFTER_PERSIST); } /** * Return whether there are listeners or callbacks for the given source. */ public boolean hasDeleteListeners(Object source, ClassMetaData meta) { - return hasCallbacks(source, meta, LifecycleEvent.BEFORE_DELETE) - || hasCallbacks(source, meta, LifecycleEvent.AFTER_DELETE) - || hasListeners(source, meta, LifecycleEvent.AFTER_DELETE); + return hasHandlers(source, meta, LifecycleEvent.BEFORE_DELETE) + || hasHandlers(source, meta, LifecycleEvent.AFTER_DELETE); } /** * Return whether there are listeners or callbacks for the given source. */ public boolean hasClearListeners(Object source, ClassMetaData meta) { - return hasCallbacks(source, meta, LifecycleEvent.BEFORE_CLEAR) - || hasCallbacks(source, meta, LifecycleEvent.AFTER_CLEAR) - || hasListeners(source, meta, LifecycleEvent.AFTER_CLEAR); + return hasHandlers(source, meta, LifecycleEvent.BEFORE_CLEAR) + || hasHandlers(source, meta, LifecycleEvent.AFTER_CLEAR); } /** * Return whether there are listeners or callbacks for the given source. */ public boolean hasLoadListeners(Object source, ClassMetaData meta) { - return hasCallbacks(source, meta, LifecycleEvent.AFTER_LOAD) - || hasListeners(source, meta, LifecycleEvent.AFTER_LOAD); + return hasHandlers(source, meta, LifecycleEvent.AFTER_LOAD); } /** * Return whether there are listeners or callbacks for the given source. */ public boolean hasStoreListeners(Object source, ClassMetaData meta) { - return hasCallbacks(source, meta, LifecycleEvent.BEFORE_STORE) - || hasCallbacks(source, meta, LifecycleEvent.AFTER_STORE) - || hasListeners(source, meta, LifecycleEvent.AFTER_STORE); + return hasHandlers(source, meta, LifecycleEvent.BEFORE_STORE) + || hasHandlers(source, meta, LifecycleEvent.AFTER_STORE); } /** * Return whether there are listeners or callbacks for the given source. */ public boolean hasDirtyListeners(Object source, ClassMetaData meta) { - return hasCallbacks(source, meta, LifecycleEvent.BEFORE_DIRTY) - || hasCallbacks(source, meta, LifecycleEvent.AFTER_DIRTY) - || hasCallbacks(source, meta, LifecycleEvent.BEFORE_DIRTY_FLUSHED) - || hasCallbacks(source, meta, LifecycleEvent.AFTER_DIRTY_FLUSHED) - || hasListeners(source, meta, LifecycleEvent.AFTER_DIRTY); + return hasHandlers(source, meta, LifecycleEvent.BEFORE_DIRTY) + || hasHandlers(source, meta, LifecycleEvent.AFTER_DIRTY); } /** * Return whether there are listeners or callbacks for the given source. */ public boolean hasDetachListeners(Object source, ClassMetaData meta) { - return hasCallbacks(source, meta, LifecycleEvent.BEFORE_DETACH) - || hasCallbacks(source, meta, LifecycleEvent.AFTER_DETACH) - || hasListeners(source, meta, LifecycleEvent.BEFORE_DETACH) - || hasListeners(source, meta, LifecycleEvent.AFTER_DETACH); + return hasHandlers(source, meta, LifecycleEvent.BEFORE_DETACH) + || hasHandlers(source, meta, LifecycleEvent.AFTER_DETACH); } /** * Return whether there are listeners or callbacks for the given source. */ public boolean hasAttachListeners(Object source, ClassMetaData meta) { - return hasCallbacks(source, meta, LifecycleEvent.BEFORE_ATTACH) - || hasCallbacks(source, meta, LifecycleEvent.AFTER_ATTACH) - || hasListeners(source, meta, LifecycleEvent.BEFORE_ATTACH) - || hasListeners(source, meta, LifecycleEvent.AFTER_ATTACH); + return hasHandlers(source, meta, LifecycleEvent.BEFORE_ATTACH) + || hasHandlers(source, meta, LifecycleEvent.AFTER_ATTACH); + } + + private boolean hasHandlers(Object source, ClassMetaData meta, int type) { + return hasCallbacks(source, meta, type) + || hasListeners(source, meta, type); } /** @@ -557,8 +550,10 @@ public class LifecycleEventManager return types; } - if (listener instanceof PersistListener) + if (listener instanceof PersistListener) { + types |= 2 << LifecycleEvent.BEFORE_PERSIST; types |= 2 << LifecycleEvent.AFTER_PERSIST; + } if (listener instanceof ClearListener) { types |= 2 << LifecycleEvent.BEFORE_CLEAR; types |= 2 << LifecycleEvent.AFTER_CLEAR; diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java index 82d4abb60..cd1e215a2 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java @@ -218,8 +218,7 @@ public abstract class AbstractBrokerFactory Map.Entry entry; for (Iterator itr = _transactionListeners.iterator(); itr.hasNext(); ) { - entry = (Map.Entry) itr.next(); - broker.addTransactionListener(entry.getKey()); + broker.addTransactionListener(itr.next()); } } } diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestBrokerFactoryListenerRegistry.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestBrokerFactoryListenerRegistry.java new file mode 100644 index 000000000..ffd476653 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestBrokerFactoryListenerRegistry.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.openjpa.kernel; + +import javax.persistence.EntityManager; + +import org.apache.openjpa.persistence.test.SingleEMFTestCase; +import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory; +import org.apache.openjpa.persistence.simple.AllFieldTypes; +import org.apache.openjpa.event.AbstractLifecycleListener; +import org.apache.openjpa.event.AbstractTransactionListener; +import org.apache.openjpa.event.LifecycleEvent; +import org.apache.openjpa.event.TransactionEvent; + +public class TestBrokerFactoryListenerRegistry + extends SingleEMFTestCase { + + private int persistCount = 0; + private int beginCount = 0; + + @Override + protected void setUp() { + super.setUp(AllFieldTypes.class); + } + + @Override + protected OpenJPAEntityManagerFactory createEMF(Object... props) { + OpenJPAEntityManagerFactory emf = super.createEMF(props); + emf.addLifecycleListener(new AbstractLifecycleListener() { + @Override + public void beforePersist(LifecycleEvent event) { + persistCount++; + } + }, null); + emf.addTransactionListener(new AbstractTransactionListener() { + @Override + public void afterBegin(TransactionEvent event) { + beginCount++; + } + }); + return emf; + } + + public void testLifecycleListenerRegistry() { + beginCount = 0; + persistCount = 0; + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + try { + em.persist(new AllFieldTypes()); + em.flush(); + assertEquals(1, beginCount); + assertEquals(1, persistCount); + } finally { + em.getTransaction().rollback(); + em.close(); + } + } +} diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java index f26148a09..bbd367613 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java @@ -272,6 +272,14 @@ public class EntityManagerFactoryImpl _factory.removeLifecycleListener(listener); } + public void addTransactionListener(Object listener) { + _factory.addTransactionListener(listener); + } + + public void removeTransactionListener(Object listener) { + _factory.removeTransactionListener(listener); + } + public void close() { _factory.close(); } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityManagerFactory.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityManagerFactory.java index 01a9f5e2e..2d3ee0eee 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityManagerFactory.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityManagerFactory.java @@ -93,7 +93,7 @@ public interface OpenJPAEntityManagerFactory * Register a listener for lifecycle-related events on the specified * classes. If the classes are null, all events will be propagated to * the listener. The listener will be passed on to all new entity - * managers. See the org.apache.openjpa.event package for + * managers. See the org.apache.openjpa.event package for * listener types. * * @since 0.3.3 @@ -106,4 +106,21 @@ public interface OpenJPAEntityManagerFactory * @since 0.3.3 */ public void removeLifecycleListener (Object listener); + + /** + * Register a listener for transaction-related events on the specified + * classes. The listener will be passed on to all new entity + * managers. See the org.apache.openjpa.event package for + * listener types. + * + * @since 1.0.0 + */ + public void addTransactionListener(Object listener); + + /** + * Remove a listener for transaction-related events. + * + * @since 1.0.0 + */ + public void removeTransactionListener (Object listener); }