You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2008/03/25 04:38:02 UTC
svn commit: r640685 [4/14] - in /openjpa/trunk: ./ openjpa-all/
openjpa-jdbc-5/ openjpa-jdbc/
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/
openjpa-jdbc/src/main/java/org/apache/open...
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCRegistry.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCRegistry.java?rev=640685&r1=640684&r2=640685&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCRegistry.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCRegistry.java Mon Mar 24 20:37:56 2008
@@ -1,288 +1,288 @@
-/*
- * 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.enhance;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Map;
-
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.util.ReferenceMap;
-import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
-import org.apache.openjpa.util.UserException;
-import org.apache.openjpa.util.InvalidStateException;
-
-/**
- * Tracks registered persistence-capable classes.
- *
- * @since 0.4.0
- * @author Abe White
- */
-public class PCRegistry {
- // DO NOT ADD ADDITIONAL DEPENDENCIES TO THIS CLASS
-
- private static final Localizer _loc = Localizer.forPackage
- (PCRegistry.class);
-
- // map of pc classes to meta structs; weak so the VM can GC classes
- private static final Map _metas = new ConcurrentReferenceHashMap
- (ReferenceMap.WEAK, ReferenceMap.HARD);
-
- // register class listeners
- private static final Collection _listeners = new LinkedList();
-
- /**
- * Register a {@link RegisterClassListener}.
- */
- public static void addRegisterClassListener(RegisterClassListener rcl) {
- if (rcl == null)
- return;
-
- // we have to be positive that every listener gets notified for
- // every class, so lots of locking
- synchronized (_listeners) {
- _listeners.add(rcl);
- }
- synchronized (_metas) {
- for (Iterator itr = _metas.keySet().iterator(); itr.hasNext();)
- rcl.register((Class) itr.next());
- }
- }
-
- /**
- * Removes a {@link RegisterClassListener}.
- */
- public static void removeRegisterClassListener(RegisterClassListener rcl) {
- synchronized (_listeners) {
- _listeners.remove(rcl);
- }
- }
-
- /**
- * Get the field names for a <code>PersistenceCapable</code> class.
- */
- public static String[] getFieldNames(Class pcClass) {
- Meta meta = getMeta(pcClass);
- return meta.fieldNames;
- }
-
- /**
- * Get the field types for a <code>PersistenceCapable</code> class.
- */
- public static Class[] getFieldTypes(Class pcClass) {
- Meta meta = getMeta(pcClass);
- return meta.fieldTypes;
- }
-
- /**
- * Return the persistent superclass for a <code>PersistenceCapable</code>
- * class, or null if none. The superclass may or may not implement
- * {@link PersistenceCapable}, depending on the access type of the class.
- */
- public static Class getPersistentSuperclass(Class pcClass) {
- Meta meta = getMeta(pcClass);
- return meta.pcSuper;
- }
-
- /**
- * Create a new instance of the class and assign its state manager.
- * The new instance has its flags set to <code>LOAD_REQUIRED</code>.
- */
- public static PersistenceCapable newInstance(Class pcClass,
- StateManager sm, boolean clear) {
- Meta meta = getMeta(pcClass);
- return (meta.pc == null) ? null : meta.pc.pcNewInstance(sm, clear);
- }
-
- /**
- * Create a new instance of the class and assign its state manager and oid.
- * The new instance has its flags set to <code>LOAD_REQUIRED</code>.
- */
- public static PersistenceCapable newInstance(Class pcClass,
- StateManager sm, Object oid, boolean clear) {
- Meta meta = getMeta(pcClass);
- return (meta.pc == null) ? null : meta.pc.pcNewInstance(sm, oid, clear);
- }
-
- /**
- * Return the persistence-capable type for <code>type</code>. This might
- * be a generated subclass of <code>type</code>.
- *
- * @since 1.1.0
- */
- public static Class getPCType(Class type) {
- Meta meta = getMeta(type);
- return (meta.pc == null) ? null : meta.pc.getClass();
- }
-
- /**
- * Create a new identity object for the given
- * <code>PersistenceCapable</code> class.
- */
- public static Object newObjectId(Class pcClass) {
- Meta meta = getMeta(pcClass);
- return (meta.pc == null) ? null : meta.pc.pcNewObjectIdInstance();
- }
-
- /**
- * Create a new identity object for the given
- * <code>PersistenceCapable</code> class, using the <code>String</code>
- * form of the constructor.
- */
- public static Object newObjectId(Class pcClass, String str) {
- Meta meta = getMeta(pcClass);
- return (meta.pc == null) ? null : meta.pc.pcNewObjectIdInstance(str);
- }
-
- /**
- * Return the alias for the given type.
- */
- public static String getTypeAlias(Class pcClass) {
- return getMeta(pcClass).alias;
- }
-
- /**
- * Copy fields from an outside source to the key fields in the identity
- * object.
- */
- public static void copyKeyFieldsToObjectId(Class pcClass, FieldSupplier fm,
- Object oid) {
- Meta meta = getMeta(pcClass);
- if (meta.pc == null)
- throw new UserException(_loc.get("copy-no-id", pcClass));
-
- meta.pc.pcCopyKeyFieldsToObjectId(fm, oid);
- }
-
- /**
- * Copy fields to an outside source from the key fields in the identity
- * object.
- */
- public static void copyKeyFieldsFromObjectId(Class pcClass,
- FieldConsumer fm, Object oid) {
- Meta meta = getMeta(pcClass);
- if (meta.pc == null)
- throw new UserException(_loc.get("copy-no-id", pcClass));
-
- meta.pc.pcCopyKeyFieldsFromObjectId(fm, oid);
- }
-
- /**
- * Register metadata by class.
- *
- * @param fieldTypes managed field types
- * @param fieldFlags managed field flags
- * @param sup the most immediate persistent superclass
- * @param pcClass the <code>PersistenceCapable</code> class
- * @param fieldNames managed field names
- * @param alias the class alias
- * @param pc an instance of the class, if not abstract
- */
- public static void register(Class pcClass, String[] fieldNames,
- Class[] fieldTypes, byte[] fieldFlags, Class sup, String alias,
- PersistenceCapable pc) {
- if (pcClass == null)
- throw new NullPointerException();
-
- // we have to be positive that every listener gets notified for
- // every class, so lots of locking
- Meta meta = new Meta(pc, fieldNames, fieldTypes, sup, alias);
- synchronized (_metas) {
- _metas.put(pcClass, meta);
- }
- synchronized (_listeners) {
- for (Iterator i = _listeners.iterator(); i.hasNext();)
- ((RegisterClassListener) i.next()).register(pcClass);
- }
- }
-
- /**
- * De-Register all metadata associated with the given ClassLoader.
- * Allows ClassLoaders to be garbage collected.
- *
- * @param cl the ClassLoader
- */
- public static void deRegister(ClassLoader cl) {
- synchronized (_metas) {
- for (Iterator i = _metas.keySet().iterator(); i.hasNext();) {
- Class pcClass = (Class) i.next();
- if (pcClass.getClassLoader() == cl) {
- _metas.remove(pcClass);
- }
- }
- }
- }
-
- /**
- * Returns a collection of class objects of the registered
- * persistence-capable classes.
- */
- public static Collection getRegisteredTypes() {
- return Collections.unmodifiableCollection(_metas.keySet());
- }
-
- /**
- * Returns <code>true</code> if <code>cls</code> is already registered.
- */
- public static boolean isRegistered(Class cls) {
- return _metas.containsKey(cls);
- }
-
- /**
- * Look up the metadata for a <code>PersistenceCapable</code> class.
- */
- private static Meta getMeta(Class pcClass) {
- Meta ret = (Meta) _metas.get(pcClass);
- if (ret == null)
- throw new IllegalStateException(_loc.get("no-meta", pcClass).
- getMessage());
- return ret;
- }
-
- /**
- * Listener for persistent class registration events.
- */
- public static interface RegisterClassListener {
-
- public void register(Class cls);
- }
-
- /**
- * This is a helper class to manage metadata per persistence-capable class.
- */
- private static class Meta {
-
- public final PersistenceCapable pc;
- public final String[] fieldNames;
- public final Class[] fieldTypes;
- public final Class pcSuper;
- public final String alias;
-
- public Meta(PersistenceCapable pc, String[] fieldNames,
- Class[] fieldTypes, Class pcSuper, String alias) {
- this.pc = pc;
- this.fieldNames = fieldNames;
- this.fieldTypes = fieldTypes;
- this.pcSuper = pcSuper;
- this.alias = alias;
- }
- }
-}
+/*
+ * 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.enhance;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.ReferenceMap;
+import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap;
+import org.apache.openjpa.util.UserException;
+import org.apache.openjpa.util.InvalidStateException;
+
+/**
+ * Tracks registered persistence-capable classes.
+ *
+ * @since 0.4.0
+ * @author Abe White
+ */
+public class PCRegistry {
+ // DO NOT ADD ADDITIONAL DEPENDENCIES TO THIS CLASS
+
+ private static final Localizer _loc = Localizer.forPackage
+ (PCRegistry.class);
+
+ // map of pc classes to meta structs; weak so the VM can GC classes
+ private static final Map _metas = new ConcurrentReferenceHashMap
+ (ReferenceMap.WEAK, ReferenceMap.HARD);
+
+ // register class listeners
+ private static final Collection _listeners = new LinkedList();
+
+ /**
+ * Register a {@link RegisterClassListener}.
+ */
+ public static void addRegisterClassListener(RegisterClassListener rcl) {
+ if (rcl == null)
+ return;
+
+ // we have to be positive that every listener gets notified for
+ // every class, so lots of locking
+ synchronized (_listeners) {
+ _listeners.add(rcl);
+ }
+ synchronized (_metas) {
+ for (Iterator itr = _metas.keySet().iterator(); itr.hasNext();)
+ rcl.register((Class) itr.next());
+ }
+ }
+
+ /**
+ * Removes a {@link RegisterClassListener}.
+ */
+ public static void removeRegisterClassListener(RegisterClassListener rcl) {
+ synchronized (_listeners) {
+ _listeners.remove(rcl);
+ }
+ }
+
+ /**
+ * Get the field names for a <code>PersistenceCapable</code> class.
+ */
+ public static String[] getFieldNames(Class pcClass) {
+ Meta meta = getMeta(pcClass);
+ return meta.fieldNames;
+ }
+
+ /**
+ * Get the field types for a <code>PersistenceCapable</code> class.
+ */
+ public static Class[] getFieldTypes(Class pcClass) {
+ Meta meta = getMeta(pcClass);
+ return meta.fieldTypes;
+ }
+
+ /**
+ * Return the persistent superclass for a <code>PersistenceCapable</code>
+ * class, or null if none. The superclass may or may not implement
+ * {@link PersistenceCapable}, depending on the access type of the class.
+ */
+ public static Class getPersistentSuperclass(Class pcClass) {
+ Meta meta = getMeta(pcClass);
+ return meta.pcSuper;
+ }
+
+ /**
+ * Create a new instance of the class and assign its state manager.
+ * The new instance has its flags set to <code>LOAD_REQUIRED</code>.
+ */
+ public static PersistenceCapable newInstance(Class pcClass,
+ StateManager sm, boolean clear) {
+ Meta meta = getMeta(pcClass);
+ return (meta.pc == null) ? null : meta.pc.pcNewInstance(sm, clear);
+ }
+
+ /**
+ * Create a new instance of the class and assign its state manager and oid.
+ * The new instance has its flags set to <code>LOAD_REQUIRED</code>.
+ */
+ public static PersistenceCapable newInstance(Class pcClass,
+ StateManager sm, Object oid, boolean clear) {
+ Meta meta = getMeta(pcClass);
+ return (meta.pc == null) ? null : meta.pc.pcNewInstance(sm, oid, clear);
+ }
+
+ /**
+ * Return the persistence-capable type for <code>type</code>. This might
+ * be a generated subclass of <code>type</code>.
+ *
+ * @since 1.1.0
+ */
+ public static Class getPCType(Class type) {
+ Meta meta = getMeta(type);
+ return (meta.pc == null) ? null : meta.pc.getClass();
+ }
+
+ /**
+ * Create a new identity object for the given
+ * <code>PersistenceCapable</code> class.
+ */
+ public static Object newObjectId(Class pcClass) {
+ Meta meta = getMeta(pcClass);
+ return (meta.pc == null) ? null : meta.pc.pcNewObjectIdInstance();
+ }
+
+ /**
+ * Create a new identity object for the given
+ * <code>PersistenceCapable</code> class, using the <code>String</code>
+ * form of the constructor.
+ */
+ public static Object newObjectId(Class pcClass, String str) {
+ Meta meta = getMeta(pcClass);
+ return (meta.pc == null) ? null : meta.pc.pcNewObjectIdInstance(str);
+ }
+
+ /**
+ * Return the alias for the given type.
+ */
+ public static String getTypeAlias(Class pcClass) {
+ return getMeta(pcClass).alias;
+ }
+
+ /**
+ * Copy fields from an outside source to the key fields in the identity
+ * object.
+ */
+ public static void copyKeyFieldsToObjectId(Class pcClass, FieldSupplier fm,
+ Object oid) {
+ Meta meta = getMeta(pcClass);
+ if (meta.pc == null)
+ throw new UserException(_loc.get("copy-no-id", pcClass));
+
+ meta.pc.pcCopyKeyFieldsToObjectId(fm, oid);
+ }
+
+ /**
+ * Copy fields to an outside source from the key fields in the identity
+ * object.
+ */
+ public static void copyKeyFieldsFromObjectId(Class pcClass,
+ FieldConsumer fm, Object oid) {
+ Meta meta = getMeta(pcClass);
+ if (meta.pc == null)
+ throw new UserException(_loc.get("copy-no-id", pcClass));
+
+ meta.pc.pcCopyKeyFieldsFromObjectId(fm, oid);
+ }
+
+ /**
+ * Register metadata by class.
+ *
+ * @param fieldTypes managed field types
+ * @param fieldFlags managed field flags
+ * @param sup the most immediate persistent superclass
+ * @param pcClass the <code>PersistenceCapable</code> class
+ * @param fieldNames managed field names
+ * @param alias the class alias
+ * @param pc an instance of the class, if not abstract
+ */
+ public static void register(Class pcClass, String[] fieldNames,
+ Class[] fieldTypes, byte[] fieldFlags, Class sup, String alias,
+ PersistenceCapable pc) {
+ if (pcClass == null)
+ throw new NullPointerException();
+
+ // we have to be positive that every listener gets notified for
+ // every class, so lots of locking
+ Meta meta = new Meta(pc, fieldNames, fieldTypes, sup, alias);
+ synchronized (_metas) {
+ _metas.put(pcClass, meta);
+ }
+ synchronized (_listeners) {
+ for (Iterator i = _listeners.iterator(); i.hasNext();)
+ ((RegisterClassListener) i.next()).register(pcClass);
+ }
+ }
+
+ /**
+ * De-Register all metadata associated with the given ClassLoader.
+ * Allows ClassLoaders to be garbage collected.
+ *
+ * @param cl the ClassLoader
+ */
+ public static void deRegister(ClassLoader cl) {
+ synchronized (_metas) {
+ for (Iterator i = _metas.keySet().iterator(); i.hasNext();) {
+ Class pcClass = (Class) i.next();
+ if (pcClass.getClassLoader() == cl) {
+ _metas.remove(pcClass);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns a collection of class objects of the registered
+ * persistence-capable classes.
+ */
+ public static Collection getRegisteredTypes() {
+ return Collections.unmodifiableCollection(_metas.keySet());
+ }
+
+ /**
+ * Returns <code>true</code> if <code>cls</code> is already registered.
+ */
+ public static boolean isRegistered(Class cls) {
+ return _metas.containsKey(cls);
+ }
+
+ /**
+ * Look up the metadata for a <code>PersistenceCapable</code> class.
+ */
+ private static Meta getMeta(Class pcClass) {
+ Meta ret = (Meta) _metas.get(pcClass);
+ if (ret == null)
+ throw new IllegalStateException(_loc.get("no-meta", pcClass).
+ getMessage());
+ return ret;
+ }
+
+ /**
+ * Listener for persistent class registration events.
+ */
+ public static interface RegisterClassListener {
+
+ public void register(Class cls);
+ }
+
+ /**
+ * This is a helper class to manage metadata per persistence-capable class.
+ */
+ private static class Meta {
+
+ public final PersistenceCapable pc;
+ public final String[] fieldNames;
+ public final Class[] fieldTypes;
+ public final Class pcSuper;
+ public final String alias;
+
+ public Meta(PersistenceCapable pc, String[] fieldNames,
+ Class[] fieldTypes, Class pcSuper, String alias) {
+ this.pc = pc;
+ this.fieldNames = fieldNames;
+ this.fieldTypes = fieldTypes;
+ this.pcSuper = pcSuper;
+ this.alias = alias;
+ }
+ }
+}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/RemoteCommitEventManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/RemoteCommitEventManager.java?rev=640685&r1=640684&r2=640685&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/RemoteCommitEventManager.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/RemoteCommitEventManager.java Mon Mar 24 20:37:56 2008
@@ -1,253 +1,253 @@
-/*
- * 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.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Collections;
-
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.kernel.Broker;
-import org.apache.openjpa.kernel.OpenJPAStateManager;
-import org.apache.openjpa.lib.util.Closeable;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
-import org.apache.openjpa.util.UserException;
-
-/**
- * Manager that can be used to track and notify
- * {@link RemoteCommitListener}s on remote commit events. If remote events
- * are enabled, this manager should be installed as a transaction listener on
- * all brokers so that it knows when commits are made.
- *
- * @author Patrick Linskey
- * @author Abe White
- * @since 0.3.0
- */
-public class RemoteCommitEventManager
- extends AbstractConcurrentEventManager
- implements EndTransactionListener, Closeable {
-
- private static final Localizer _loc = Localizer.forPackage
- (RemoteCommitEventManager.class);
-
- private final RemoteCommitProvider _provider;
- private boolean _transmitPersIds = false;
-
- /**
- * Constructor. Supply configuration.
- */
- public RemoteCommitEventManager(OpenJPAConfiguration conf) {
- _provider = conf.newRemoteCommitProviderInstance();
- if (_provider != null) {
- _provider.setRemoteCommitEventManager(this);
- }
- }
-
- /**
- * Return true if remote events are enabled.
- */
- public boolean areRemoteEventsEnabled() {
- return _provider != null;
- }
-
- /**
- * Return the {@link RemoteCommitProvider} that this manager uses.
- *
- * @since 0.3.1
- */
- public RemoteCommitProvider getRemoteCommitProvider() {
- return _provider;
- }
-
- /**
- * Whether the oids of added instances will be transmitted.
- */
- public boolean getTransmitPersistedObjectIds() {
- return _transmitPersIds;
- }
-
- /**
- * Whether the oids of added instances will be transmitted.
- */
- public void setTransmitPersistedObjectIds(boolean transmit) {
- _transmitPersIds = transmit;
- }
-
- /**
- * Adds an OpenJPA-internal listener to this RemoteCommitEventManager.
- * Listeners so registered will be fired before any that are registered
- * via {@link #addListener}. This means that the external listeners can
- * rely on internal caches and data structures being up-to-date by the
- * time that they are invoked.
- *
- * @since 1.0.0
- */
- public void addInternalListener(RemoteCommitListener listen) {
- if (_provider == null)
- throw new UserException(_loc.get("no-provider"));
- ((List) _listeners).add(0, listen);
- }
-
- public void addListener(RemoteCommitListener listen) {
- if (_provider == null)
- throw new UserException(_loc.get("no-provider"));
- super.addListener(listen);
- }
-
- /**
- * Close this manager and all registered listeners.
- */
- public void close() {
- if (_provider != null) {
- _provider.close();
- Collection listeners = getListeners();
- for (Iterator itr = listeners.iterator(); itr.hasNext();)
- ((RemoteCommitListener) itr.next()).close();
- }
- }
-
- protected void fireEvent(Object event, Object listener) {
- RemoteCommitListener listen = (RemoteCommitListener) listener;
- RemoteCommitEvent ev = (RemoteCommitEvent) event;
- listen.afterCommit(ev);
- }
-
- /**
- * Fire an event to local listeners only notifying them of a detected
- * stale record.
- *
- * @since 1.0.0
- */
- public void fireLocalStaleNotification(Object oid) {
- RemoteCommitEvent ev = new RemoteCommitEvent(
- RemoteCommitEvent.PAYLOAD_LOCAL_STALE_DETECTION,
- null, null, Collections.singleton(oid), null);
- fireEvent(ev);
- }
-
- //////////////////////////////////////
- // TransactionListener implementation
- //////////////////////////////////////
-
- public void afterCommit(TransactionEvent event) {
- if (_provider != null) {
- RemoteCommitEvent rce = createRemoteCommitEvent(event);
- if (rce != null)
- _provider.broadcast(rce);
- }
- }
-
- /**
- * Create a remote commit event from the given transaction event.
- */
- private RemoteCommitEvent createRemoteCommitEvent(TransactionEvent event) {
- Broker broker = (Broker) event.getSource();
- int payload;
- Collection persIds = null;
- Collection addClassNames = null;
- Collection updates = null;
- Collection deletes = null;
-
- if (broker.isTrackChangesByType()) {
- payload = RemoteCommitEvent.PAYLOAD_EXTENTS;
- addClassNames = toClassNames(event.getPersistedTypes());
- updates = toClassNames(event.getUpdatedTypes());
- deletes = toClassNames(event.getDeletedTypes());
- if (addClassNames == null && updates == null && deletes == null)
- return null;
- } else {
- Collection trans = event.getTransactionalObjects();
- if (trans.isEmpty())
- return null;
-
- payload = (_transmitPersIds)
- ? RemoteCommitEvent.PAYLOAD_OIDS_WITH_ADDS
- : RemoteCommitEvent.PAYLOAD_OIDS;
- Object oid;
- Object obj;
- OpenJPAStateManager sm;
- for (Iterator itr = trans.iterator(); itr.hasNext();) {
- obj = itr.next();
- sm = broker.getStateManager(obj);
-
- if (sm == null || !sm.isPersistent() || !sm.isDirty())
- continue;
- if (sm.isNew() && sm.isDeleted())
- continue;
-
- oid = sm.fetchObjectId();
- if (sm.isNew()) {
- if (_transmitPersIds) {
- if (persIds == null)
- persIds = new ArrayList();
- persIds.add(oid);
- }
- if (addClassNames == null)
- addClassNames = new HashSet();
- addClassNames.add(obj.getClass().getName());
- } else if (sm.isDeleted()) {
- if (deletes == null)
- deletes = new ArrayList();
- deletes.add(oid);
- } else {
- if (updates == null)
- updates = new ArrayList();
- updates.add(oid);
- }
- }
- if (addClassNames == null && updates == null && deletes == null)
- return null;
- }
- return new RemoteCommitEvent(payload, persIds, addClassNames, updates,
- deletes);
- }
-
- /**
- * Transform a collection of classes to class names.
- */
- private static Collection toClassNames(Collection clss) {
- if (clss.isEmpty())
- return null;
-
- List names = new ArrayList(clss);
- for (int i = 0; i < names.size(); i++)
- names.set(i, ((Class) names.get(i)).getName());
- return names;
- }
-
- public void beforeCommit(TransactionEvent event) {
- }
-
- public void afterRollback(TransactionEvent event) {
- }
-
- public void afterCommitComplete(TransactionEvent event) {
- }
-
- public void afterRollbackComplete(TransactionEvent event) {
- }
-
- public void afterStateTransitions(TransactionEvent event)
- {
- }
-}
+/*
+ * 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.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Collections;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.util.Closeable;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * Manager that can be used to track and notify
+ * {@link RemoteCommitListener}s on remote commit events. If remote events
+ * are enabled, this manager should be installed as a transaction listener on
+ * all brokers so that it knows when commits are made.
+ *
+ * @author Patrick Linskey
+ * @author Abe White
+ * @since 0.3.0
+ */
+public class RemoteCommitEventManager
+ extends AbstractConcurrentEventManager
+ implements EndTransactionListener, Closeable {
+
+ private static final Localizer _loc = Localizer.forPackage
+ (RemoteCommitEventManager.class);
+
+ private final RemoteCommitProvider _provider;
+ private boolean _transmitPersIds = false;
+
+ /**
+ * Constructor. Supply configuration.
+ */
+ public RemoteCommitEventManager(OpenJPAConfiguration conf) {
+ _provider = conf.newRemoteCommitProviderInstance();
+ if (_provider != null) {
+ _provider.setRemoteCommitEventManager(this);
+ }
+ }
+
+ /**
+ * Return true if remote events are enabled.
+ */
+ public boolean areRemoteEventsEnabled() {
+ return _provider != null;
+ }
+
+ /**
+ * Return the {@link RemoteCommitProvider} that this manager uses.
+ *
+ * @since 0.3.1
+ */
+ public RemoteCommitProvider getRemoteCommitProvider() {
+ return _provider;
+ }
+
+ /**
+ * Whether the oids of added instances will be transmitted.
+ */
+ public boolean getTransmitPersistedObjectIds() {
+ return _transmitPersIds;
+ }
+
+ /**
+ * Whether the oids of added instances will be transmitted.
+ */
+ public void setTransmitPersistedObjectIds(boolean transmit) {
+ _transmitPersIds = transmit;
+ }
+
+ /**
+ * Adds an OpenJPA-internal listener to this RemoteCommitEventManager.
+ * Listeners so registered will be fired before any that are registered
+ * via {@link #addListener}. This means that the external listeners can
+ * rely on internal caches and data structures being up-to-date by the
+ * time that they are invoked.
+ *
+ * @since 1.0.0
+ */
+ public void addInternalListener(RemoteCommitListener listen) {
+ if (_provider == null)
+ throw new UserException(_loc.get("no-provider"));
+ ((List) _listeners).add(0, listen);
+ }
+
+ public void addListener(RemoteCommitListener listen) {
+ if (_provider == null)
+ throw new UserException(_loc.get("no-provider"));
+ super.addListener(listen);
+ }
+
+ /**
+ * Close this manager and all registered listeners.
+ */
+ public void close() {
+ if (_provider != null) {
+ _provider.close();
+ Collection listeners = getListeners();
+ for (Iterator itr = listeners.iterator(); itr.hasNext();)
+ ((RemoteCommitListener) itr.next()).close();
+ }
+ }
+
+ protected void fireEvent(Object event, Object listener) {
+ RemoteCommitListener listen = (RemoteCommitListener) listener;
+ RemoteCommitEvent ev = (RemoteCommitEvent) event;
+ listen.afterCommit(ev);
+ }
+
+ /**
+ * Fire an event to local listeners only notifying them of a detected
+ * stale record.
+ *
+ * @since 1.0.0
+ */
+ public void fireLocalStaleNotification(Object oid) {
+ RemoteCommitEvent ev = new RemoteCommitEvent(
+ RemoteCommitEvent.PAYLOAD_LOCAL_STALE_DETECTION,
+ null, null, Collections.singleton(oid), null);
+ fireEvent(ev);
+ }
+
+ //////////////////////////////////////
+ // TransactionListener implementation
+ //////////////////////////////////////
+
+ public void afterCommit(TransactionEvent event) {
+ if (_provider != null) {
+ RemoteCommitEvent rce = createRemoteCommitEvent(event);
+ if (rce != null)
+ _provider.broadcast(rce);
+ }
+ }
+
+ /**
+ * Create a remote commit event from the given transaction event.
+ */
+ private RemoteCommitEvent createRemoteCommitEvent(TransactionEvent event) {
+ Broker broker = (Broker) event.getSource();
+ int payload;
+ Collection persIds = null;
+ Collection addClassNames = null;
+ Collection updates = null;
+ Collection deletes = null;
+
+ if (broker.isTrackChangesByType()) {
+ payload = RemoteCommitEvent.PAYLOAD_EXTENTS;
+ addClassNames = toClassNames(event.getPersistedTypes());
+ updates = toClassNames(event.getUpdatedTypes());
+ deletes = toClassNames(event.getDeletedTypes());
+ if (addClassNames == null && updates == null && deletes == null)
+ return null;
+ } else {
+ Collection trans = event.getTransactionalObjects();
+ if (trans.isEmpty())
+ return null;
+
+ payload = (_transmitPersIds)
+ ? RemoteCommitEvent.PAYLOAD_OIDS_WITH_ADDS
+ : RemoteCommitEvent.PAYLOAD_OIDS;
+ Object oid;
+ Object obj;
+ OpenJPAStateManager sm;
+ for (Iterator itr = trans.iterator(); itr.hasNext();) {
+ obj = itr.next();
+ sm = broker.getStateManager(obj);
+
+ if (sm == null || !sm.isPersistent() || !sm.isDirty())
+ continue;
+ if (sm.isNew() && sm.isDeleted())
+ continue;
+
+ oid = sm.fetchObjectId();
+ if (sm.isNew()) {
+ if (_transmitPersIds) {
+ if (persIds == null)
+ persIds = new ArrayList();
+ persIds.add(oid);
+ }
+ if (addClassNames == null)
+ addClassNames = new HashSet();
+ addClassNames.add(obj.getClass().getName());
+ } else if (sm.isDeleted()) {
+ if (deletes == null)
+ deletes = new ArrayList();
+ deletes.add(oid);
+ } else {
+ if (updates == null)
+ updates = new ArrayList();
+ updates.add(oid);
+ }
+ }
+ if (addClassNames == null && updates == null && deletes == null)
+ return null;
+ }
+ return new RemoteCommitEvent(payload, persIds, addClassNames, updates,
+ deletes);
+ }
+
+ /**
+ * Transform a collection of classes to class names.
+ */
+ private static Collection toClassNames(Collection clss) {
+ if (clss.isEmpty())
+ return null;
+
+ List names = new ArrayList(clss);
+ for (int i = 0; i < names.size(); i++)
+ names.set(i, ((Class) names.get(i)).getName());
+ return names;
+ }
+
+ public void beforeCommit(TransactionEvent event) {
+ }
+
+ public void afterRollback(TransactionEvent event) {
+ }
+
+ public void afterCommitComplete(TransactionEvent event) {
+ }
+
+ public void afterRollbackComplete(TransactionEvent event) {
+ }
+
+ public void afterStateTransitions(TransactionEvent event)
+ {
+ }
+}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/SingleJVMRemoteCommitProvider.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/SingleJVMRemoteCommitProvider.java?rev=640685&r1=640684&r2=640685&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/SingleJVMRemoteCommitProvider.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/SingleJVMRemoteCommitProvider.java Mon Mar 24 20:37:56 2008
@@ -1,64 +1,65 @@
-/*
- * 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.Iterator;
-import java.util.Set;
-
-import org.apache.openjpa.lib.util.concurrent.ConcurrentHashSet;
-
-/**
- * Single-JVM-only implementation of {@link RemoteCommitProvider}
- * that listens for object modifications and propagates those changes
- * to other SingleJVMRemoteCommitProviders in the same JVM. This is
- * only useful for linking together multiple factories in the same
- * JVM that are all loaded in the same classloader, which is a rare
- * circumstance.
- *
- * @author Patrick Linskey
- * @since 0.2.5.0
- */
-public class SingleJVMRemoteCommitProvider
- extends AbstractRemoteCommitProvider {
-
- private static Set s_providers = new ConcurrentHashSet();
-
- public SingleJVMRemoteCommitProvider() {
- s_providers.add(this);
- }
-
- public void broadcast(RemoteCommitEvent event) {
- SingleJVMRemoteCommitProvider provider;
- for (Iterator iter = s_providers.iterator(); iter.hasNext();) {
- provider = (SingleJVMRemoteCommitProvider) iter.next();
-
- // don't notify this object -- this provider's factory
- // should not be notified of commits that originated
- // with one of its brokers
- if (provider == this)
- continue;
-
- provider.fireEvent(event);
- }
- }
-
- public void close() {
- s_providers.remove(this);
- }
-}
+/*
+ * 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.Iterator;
+import java.util.Set;
+
+import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashSet;
+
+/**
+ * Single-JVM-only implementation of {@link RemoteCommitProvider}
+ * that listens for object modifications and propagates those changes
+ * to other SingleJVMRemoteCommitProviders in the same JVM. This is
+ * only useful for linking together multiple factories in the same
+ * JVM that are all loaded in the same classloader, which is a rare
+ * circumstance.
+ *
+ * @author Patrick Linskey
+ * @since 0.2.5.0
+ */
+public class SingleJVMRemoteCommitProvider
+ extends AbstractRemoteCommitProvider {
+
+ private static Set s_providers = new ConcurrentReferenceHashSet(
+ ConcurrentReferenceHashSet.HARD);
+
+ public SingleJVMRemoteCommitProvider() {
+ s_providers.add(this);
+ }
+
+ public void broadcast(RemoteCommitEvent event) {
+ SingleJVMRemoteCommitProvider provider;
+ for (Iterator iter = s_providers.iterator(); iter.hasNext();) {
+ provider = (SingleJVMRemoteCommitProvider) iter.next();
+
+ // don't notify this object -- this provider's factory
+ // should not be notified of commits that originated
+ // with one of its brokers
+ if (provider == this)
+ continue;
+
+ provider.fireEvent(event);
+ }
+ }
+
+ public void close() {
+ s_providers.remove(this);
+ }
+}