mirror of https://github.com/apache/openjpa.git
OPENJPA-262
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@550185 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
cbb7bded12
commit
39f1071085
|
@ -39,6 +39,7 @@ import org.apache.openjpa.kernel.QueryFlushModes;
|
|||
import org.apache.openjpa.kernel.RestoreState;
|
||||
import org.apache.openjpa.kernel.SavepointManager;
|
||||
import org.apache.openjpa.kernel.Seq;
|
||||
import org.apache.openjpa.event.BrokerFactoryEventManager;
|
||||
import org.apache.openjpa.kernel.exps.AggregateListener;
|
||||
import org.apache.openjpa.kernel.exps.FilterListener;
|
||||
import org.apache.openjpa.lib.conf.Configuration;
|
||||
|
@ -1386,4 +1387,10 @@ public interface OpenJPAConfiguration
|
|||
* configuration.
|
||||
*/
|
||||
public StoreFacadeTypeRegistry getStoreFacadeTypeRegistry();
|
||||
|
||||
/**
|
||||
* Return the {@link org.apache.openjpa.event.BrokerFactoryEventManager} associated with this
|
||||
* configuration.
|
||||
*/
|
||||
public BrokerFactoryEventManager getBrokerFactoryEventManager();
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.apache.openjpa.ee.ManagedRuntime;
|
|||
import org.apache.openjpa.event.OrphanedKeyAction;
|
||||
import org.apache.openjpa.event.RemoteCommitEventManager;
|
||||
import org.apache.openjpa.event.RemoteCommitProvider;
|
||||
import org.apache.openjpa.event.BrokerFactoryEventManager;
|
||||
import org.apache.openjpa.kernel.AutoClear;
|
||||
import org.apache.openjpa.kernel.BrokerImpl;
|
||||
import org.apache.openjpa.kernel.ConnectionRetainModes;
|
||||
|
@ -140,6 +141,8 @@ public class OpenJPAConfigurationImpl
|
|||
private String spec = null;
|
||||
private final StoreFacadeTypeRegistry _storeFacadeRegistry =
|
||||
new StoreFacadeTypeRegistry();
|
||||
private BrokerFactoryEventManager _brokerFactoryEventManager =
|
||||
new BrokerFactoryEventManager(this);
|
||||
|
||||
/**
|
||||
* Default constructor. Attempts to load global properties.
|
||||
|
@ -1409,6 +1412,10 @@ public class OpenJPAConfigurationImpl
|
|||
return _storeFacadeRegistry;
|
||||
}
|
||||
|
||||
public BrokerFactoryEventManager getBrokerFactoryEventManager() {
|
||||
return _brokerFactoryEventManager;
|
||||
}
|
||||
|
||||
public void instantiateAll() {
|
||||
super.instantiateAll();
|
||||
getMetaDataRepositoryInstance();
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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.event;
|
||||
|
||||
import java.util.EventObject;
|
||||
|
||||
import org.apache.openjpa.kernel.BrokerFactory;
|
||||
|
||||
/**
|
||||
* Event fired when a {@link BrokerFactory} is created.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class BrokerFactoryEvent
|
||||
extends EventObject {
|
||||
|
||||
public final static int BROKER_FACTORY_CREATED = 0;
|
||||
|
||||
private int eventType;
|
||||
|
||||
public BrokerFactoryEvent(BrokerFactory brokerFactory, int eventType) {
|
||||
super(brokerFactory);
|
||||
this.eventType = eventType;
|
||||
}
|
||||
|
||||
public BrokerFactory getBrokerFactory() {
|
||||
return (BrokerFactory) getSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return one of the event type codes defined in this event class.
|
||||
*/
|
||||
public int getEventType() {
|
||||
return eventType;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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.event;
|
||||
|
||||
import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
|
||||
import org.apache.openjpa.lib.util.Localizer;
|
||||
import org.apache.openjpa.lib.conf.Configuration;
|
||||
import org.apache.openjpa.conf.OpenJPAConfiguration;
|
||||
|
||||
/**
|
||||
* {@link EventManager} responsible for notifying listeners of
|
||||
* {@link BrokerFactoryEvent}s.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class BrokerFactoryEventManager
|
||||
extends AbstractConcurrentEventManager {
|
||||
|
||||
private static final Localizer _loc = Localizer.forPackage(
|
||||
BrokerFactoryEventManager.class);
|
||||
|
||||
private final Configuration _conf;
|
||||
|
||||
public BrokerFactoryEventManager(Configuration conf) {
|
||||
_conf = conf;
|
||||
}
|
||||
|
||||
protected void fireEvent(Object event, Object listener) {
|
||||
try {
|
||||
BrokerFactoryEvent e = (BrokerFactoryEvent) event;
|
||||
((BrokerFactoryListener) listener).afterBrokerFactoryCreate(e);
|
||||
} catch (Exception e) {
|
||||
_conf.getLog(OpenJPAConfiguration.LOG_RUNTIME).warn(
|
||||
_loc.get("broker-factory-listener-exception"), e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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.event;
|
||||
|
||||
/**
|
||||
* Interface for listening to {@link BrokerFactoryEvent} objects. Should be
|
||||
* registered with a {@link OpenJPAConfiguration}'s
|
||||
* {@link BrokerFactoryEventManager}.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public interface BrokerFactoryListener {
|
||||
|
||||
/**
|
||||
* Invoked after a {@link AbstractBrokerFactory} has been fully created.
|
||||
* This happens after the factory has been made read-only.
|
||||
*/
|
||||
public void afterBrokerFactoryCreate(BrokerFactoryEvent event);
|
||||
}
|
|
@ -37,6 +37,7 @@ import org.apache.openjpa.conf.OpenJPAVersion;
|
|||
import org.apache.openjpa.datacache.DataCacheStoreManager;
|
||||
import org.apache.openjpa.enhance.PCRegistry;
|
||||
import org.apache.openjpa.event.RemoteCommitEventManager;
|
||||
import org.apache.openjpa.event.BrokerFactoryEvent;
|
||||
import org.apache.openjpa.lib.log.Log;
|
||||
import org.apache.openjpa.lib.util.Localizer;
|
||||
import org.apache.openjpa.lib.util.ReferenceHashSet;
|
||||
|
@ -545,6 +546,12 @@ public abstract class AbstractBrokerFactory
|
|||
// avoid synchronization
|
||||
_conf.setReadOnly(true);
|
||||
_conf.instantiateAll();
|
||||
|
||||
// fire an event for all the broker factory listeners
|
||||
// registered on the configuration.
|
||||
_conf.getBrokerFactoryEventManager().fireEvent(
|
||||
new BrokerFactoryEvent(this,
|
||||
BrokerFactoryEvent.BROKER_FACTORY_CREATED));
|
||||
} finally {
|
||||
unlock();
|
||||
}
|
||||
|
|
|
@ -95,3 +95,5 @@ bean-constructor: Could not instantiate class {0}. Make sure it has an \
|
|||
accessible no-args constructor.
|
||||
method-notfound: Method "{1}" with arguments of type: {2} \
|
||||
not found in class "{0}".
|
||||
broker-factory-listener-exception: Exception thrown while calling a \
|
||||
BrokerFactoryListener. This exception will be ignored.
|
|
@ -1,149 +0,0 @@
|
|||
/*
|
||||
* 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.lib.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Base event manager that handles adding/removing listeners
|
||||
* and firing events. This class is reentrant-safe; listeners can be added
|
||||
* and removed by other listeners when they receive events. The changes will
|
||||
* not be visible until the event fire that initiated the recursive sequence
|
||||
* of calls completes, however.
|
||||
*
|
||||
* @author Abe White
|
||||
*/
|
||||
public abstract class AbstractEventManager implements EventManager {
|
||||
|
||||
private static Exception[] EMPTY_EXCEPTIONS = new Exception[0];
|
||||
|
||||
private boolean _firing = false;
|
||||
private Collection _listeners = null;
|
||||
private Collection _newListeners = null;
|
||||
|
||||
/**
|
||||
* Register an event listener.
|
||||
*/
|
||||
public synchronized void addListener(Object listener) {
|
||||
if (listener == null)
|
||||
return;
|
||||
if (_firing) {
|
||||
if (_newListeners == null) {
|
||||
_newListeners = newListenerCollection();
|
||||
_newListeners.addAll(_listeners);
|
||||
}
|
||||
_newListeners.add(listener);
|
||||
} else {
|
||||
if (_listeners == null)
|
||||
_listeners = newListenerCollection();
|
||||
_listeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an event listener.
|
||||
*/
|
||||
public synchronized boolean removeListener(Object listener) {
|
||||
if (listener == null)
|
||||
return false;
|
||||
if (_firing && _listeners.contains(listener)) {
|
||||
if (_newListeners == null) {
|
||||
_newListeners = newListenerCollection();
|
||||
_newListeners.addAll(_listeners);
|
||||
}
|
||||
return _newListeners.remove(listener);
|
||||
}
|
||||
return _listeners != null && _listeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the given instance is in the list of listeners.
|
||||
*/
|
||||
public synchronized boolean hasListener(Object listener) {
|
||||
return _listeners != null && _listeners.contains(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if there are any registered listeners.
|
||||
*/
|
||||
public synchronized boolean hasListeners() {
|
||||
return _listeners != null && !_listeners.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a read-only list of listeners.
|
||||
*/
|
||||
public synchronized Collection getListeners() {
|
||||
return (_listeners == null) ? Collections.EMPTY_LIST
|
||||
: Collections.unmodifiableCollection(_listeners);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire the given event to all listeners.
|
||||
*/
|
||||
public synchronized Exception[] fireEvent(Object event) {
|
||||
if (_listeners == null || _listeners.isEmpty())
|
||||
return EMPTY_EXCEPTIONS;
|
||||
|
||||
boolean reentrant = _firing;
|
||||
_firing = true;
|
||||
List exceptions = null;
|
||||
for (Iterator itr = _listeners.iterator(); itr.hasNext();) {
|
||||
try {
|
||||
fireEvent(event, itr.next());
|
||||
} catch (Exception e) {
|
||||
if (exceptions == null)
|
||||
exceptions = new LinkedList();
|
||||
exceptions.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
// if this wasn't a reentrant call, record that we're no longer
|
||||
// in the process of firing events and replace our initial listener
|
||||
// list with the set of new listeners
|
||||
if (!reentrant) {
|
||||
_firing = false;
|
||||
if (_newListeners != null)
|
||||
_listeners = _newListeners;
|
||||
_newListeners = null;
|
||||
}
|
||||
|
||||
if (exceptions == null)
|
||||
return EMPTY_EXCEPTIONS;
|
||||
return (Exception[]) exceptions.toArray
|
||||
(new Exception[exceptions.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement this method to fire the given event to the given listener.
|
||||
*/
|
||||
protected abstract void fireEvent(Object event, Object listener)
|
||||
throws Exception;
|
||||
|
||||
/**
|
||||
* Return a new container for listeners. Uses a linked list by default.
|
||||
*/
|
||||
protected Collection newListenerCollection() {
|
||||
return new LinkedList();
|
||||
}
|
||||
}
|
|
@ -22,9 +22,10 @@ import junit.framework.Test;
|
|||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
import junit.textui.TestRunner;
|
||||
import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
|
||||
|
||||
/**
|
||||
* Tests the {@link AbstractEventManager}.
|
||||
* Tests the {@link AbstractConcurrentEventManager}.
|
||||
*
|
||||
* @author Abe White
|
||||
*/
|
||||
|
@ -67,7 +68,7 @@ public class TestAbstractEventManager extends TestCase {
|
|||
TestRunner.run(suite());
|
||||
}
|
||||
|
||||
private static class EventManager extends AbstractEventManager {
|
||||
private static class EventManager extends AbstractConcurrentEventManager {
|
||||
|
||||
protected void fireEvent(Object event, Object listener) {
|
||||
((Listener) listener).fire();
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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.Persistence;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.openjpa.event.BrokerFactoryListener;
|
||||
import org.apache.openjpa.event.BrokerFactoryEvent;
|
||||
import org.apache.openjpa.persistence.OpenJPAPersistence;
|
||||
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
|
||||
|
||||
public class TestBrokerFactoryEventManager
|
||||
extends TestCase {
|
||||
|
||||
public void testCreateEvent() {
|
||||
OpenJPAEntityManagerFactory emf = OpenJPAPersistence.cast(
|
||||
Persistence.createEntityManagerFactory("test"));
|
||||
ListenerImpl listener = new ListenerImpl();
|
||||
emf.getConfiguration().getBrokerFactoryEventManager()
|
||||
.addListener(listener);
|
||||
emf.createEntityManager().close();
|
||||
assertTrue(listener.createEventReceived);
|
||||
emf.close();
|
||||
}
|
||||
|
||||
private class ListenerImpl implements BrokerFactoryListener {
|
||||
|
||||
boolean createEventReceived = false;
|
||||
|
||||
public void afterBrokerFactoryCreate(BrokerFactoryEvent event) {
|
||||
createEventReceived = true;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue