summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2007-09-15 02:37:55 (EDT)
committerEike Stepper2007-09-15 02:37:55 (EDT)
commit7a5a8945e19a6d05f9c64beae5b7e6f55a295d87 (patch)
tree1a7e07bc62262b0f4779e13a8e35f2d093e0dd7f
parent3263095d236b8c3f4d3a59ca0d5d26289671845c (diff)
downloadcdo-7a5a8945e19a6d05f9c64beae5b7e6f55a295d87.zip
cdo-7a5a8945e19a6d05f9c64beae5b7e6f55a295d87.tar.gz
cdo-7a5a8945e19a6d05f9c64beae5b7e6f55a295d87.tar.bz2
[203511] Provide vetoable transaction hooks
https://bugs.eclipse.org/bugs/show_bug.cgi?id=203511
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransaction.java19
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransactionHandler.java38
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java90
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionRequest.java30
-rw-r--r--plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/internal/util/event/Notifier.java3
5 files changed, 143 insertions, 37 deletions
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransaction.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransaction.java
index ad068b0..ac74b4d 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransaction.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransaction.java
@@ -11,12 +11,17 @@
package org.eclipse.emf.cdo;
import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.protocol.CDOID;
import org.eclipse.emf.cdo.protocol.model.CDOClass;
+import org.eclipse.emf.cdo.protocol.model.CDOPackage;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.resource.ResourceSet;
+import java.util.List;
+import java.util.Map;
+
/**
* @author Eike Stepper
*/
@@ -40,4 +45,18 @@ public interface CDOTransaction extends CDOView
* @see CDOTransaction#rollback()
*/
public void rollback();
+
+ public void addHandler(CDOTransactionHandler handler);
+
+ public void removeHandler(CDOTransactionHandler handler);
+
+ public CDOTransactionHandler[] getHandlers();
+
+ public List<CDOPackage> getNewPackages();
+
+ public Map<CDOID, CDOResource> getNewResources();
+
+ public Map<CDOID, CDOObject> getNewObjects();
+
+ public Map<CDOID, CDOObject> getDirtyObjects();
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransactionHandler.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransactionHandler.java
new file mode 100644
index 0000000..8769fa5
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransactionHandler.java
@@ -0,0 +1,38 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2007 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo;
+
+/**
+ * @author Eike Stepper
+ */
+public interface CDOTransactionHandler
+{
+ /**
+ * Called by a <code>CDOTransaction</code> <b>before</b> an object is added. The implementor of this method is
+ * allowed to throw an unchecked exception that will propagate up to the operation that is about to add the object.
+ */
+ public void addingObject(CDOTransaction transaction, CDOObject object);
+
+ /**
+ * Called by a <code>CDOTransaction</code> <b>before</b> an object is modified. The implementor of this method is
+ * allowed to throw an unchecked exception that will propagate up to the operation that is about to modify the object.
+ * <p>
+ * Note: This method will be called at most once per object until the associated transaction is committed.
+ */
+ public void modifyingObject(CDOTransaction transaction, CDOObject object);
+
+ /**
+ * Called by a <code>CDOTransaction</code> <b>before</b> it is being committed. The implementor of this method is
+ * allowed to throw an unchecked exception that will propagate up to the operation that is about to commit the
+ * transaction.
+ */
+ public void committingTransaction(CDOTransaction transaction);
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java
index ef26efc..03fb795 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java
@@ -10,13 +10,17 @@
**************************************************************************/
package org.eclipse.emf.internal.cdo;
+import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOTransaction;
import org.eclipse.emf.cdo.CDOTransactionCommittedEvent;
import org.eclipse.emf.cdo.CDOTransactionDirtyEvent;
+import org.eclipse.emf.cdo.CDOTransactionHandler;
+import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl;
import org.eclipse.emf.cdo.internal.protocol.CDOIDImpl;
import org.eclipse.emf.cdo.internal.protocol.model.CDOPackageImpl;
import org.eclipse.emf.cdo.protocol.CDOID;
+import org.eclipse.emf.cdo.protocol.model.CDOPackage;
import org.eclipse.emf.cdo.protocol.util.TransportException;
import org.eclipse.emf.ecore.EPackage;
@@ -27,6 +31,7 @@ import org.eclipse.emf.internal.cdo.util.EMFPackageClosure;
import org.eclipse.emf.internal.cdo.util.ModelUtil;
import org.eclipse.net4j.IChannel;
+import org.eclipse.net4j.internal.util.event.Notifier;
import org.eclipse.net4j.internal.util.om.trace.ContextTracer;
import org.eclipse.net4j.signal.IFailOverStrategy;
import org.eclipse.net4j.util.ImplementationError;
@@ -50,13 +55,18 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
private transient long nextTemporaryID = INITIAL_TEMPORARY_ID;
- private List<CDOPackageImpl> newPackages;
+ /**
+ * TODO Optimize by storing an array. See {@link Notifier}.
+ */
+ private List<CDOTransactionHandler> handlers = new ArrayList<CDOTransactionHandler>(0);
+
+ private List<CDOPackage> newPackages;
- private Map<CDOID, CDOResourceImpl> newResources = new HashMap<CDOID, CDOResourceImpl>();
+ private Map<CDOID, CDOResource> newResources = new HashMap<CDOID, CDOResource>();
- private Map<CDOID, InternalCDOObject> newObjects = new HashMap<CDOID, InternalCDOObject>();
+ private Map<CDOID, CDOObject> newObjects = new HashMap<CDOID, CDOObject>();
- private Map<CDOID, InternalCDOObject> dirtyObjects = new HashMap<CDOID, InternalCDOObject>();
+ private Map<CDOID, CDOObject> dirtyObjects = new HashMap<CDOID, CDOObject>();
private boolean dirty;
@@ -71,28 +81,52 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
return Type.TRANSACTION;
}
+ public void addHandler(CDOTransactionHandler handler)
+ {
+ synchronized (handlers)
+ {
+ handlers.add(handler);
+ }
+ }
+
+ public void removeHandler(CDOTransactionHandler handler)
+ {
+ synchronized (handlers)
+ {
+ handlers.remove(handler);
+ }
+ }
+
+ public CDOTransactionHandler[] getHandlers()
+ {
+ synchronized (handlers)
+ {
+ return handlers.toArray(new CDOTransactionHandler[handlers.size()]);
+ }
+ }
+
@Override
public boolean isDirty()
{
return dirty;
}
- public List<CDOPackageImpl> getNewPackages()
+ public List<CDOPackage> getNewPackages()
{
return newPackages;
}
- public Map<CDOID, CDOResourceImpl> getNewResources()
+ public Map<CDOID, CDOResource> getNewResources()
{
return newResources;
}
- public Map<CDOID, InternalCDOObject> getNewObjects()
+ public Map<CDOID, CDOObject> getNewObjects()
{
return newObjects;
}
- public Map<CDOID, InternalCDOObject> getDirtyObjects()
+ public Map<CDOID, CDOObject> getDirtyObjects()
{
return dirtyObjects;
}
@@ -115,6 +149,11 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
TRACER.trace("commit()");
}
+ for (CDOTransactionHandler handler : getHandlers())
+ {
+ handler.committingTransaction(this);
+ }
+
try
{
CDOSessionImpl session = getSession();
@@ -138,9 +177,9 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
session.notifyInvalidation(result.getTimeStamp(), dirtyObjects.keySet(), this);
}
- for (CDOPackageImpl newPackage : newPackages)
+ for (CDOPackage newPackage : newPackages)
{
- newPackage.setPersistent(true);
+ ((CDOPackageImpl)newPackage).setPersistent(true);
}
newPackages = null;
@@ -191,22 +230,22 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
public void registerNew(InternalCDOObject object)
{
- if (object instanceof CDOResourceImpl)
+ if (TRACER.isEnabled())
{
- if (TRACER.isEnabled())
- {
- TRACER.format("Registering new resource {0}", object);
- }
+ TRACER.format("Registering new object {0}", object);
+ }
+
+ for (CDOTransactionHandler handler : getHandlers())
+ {
+ handler.addingObject(this, object);
+ }
+ if (object instanceof CDOResourceImpl)
+ {
register(newResources, object);
}
else
{
- if (TRACER.isEnabled())
- {
- TRACER.format("Registering new object {0}", object);
- }
-
register(newObjects, object);
}
}
@@ -218,6 +257,11 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
TRACER.format("Registering dirty object {0}", object);
}
+ for (CDOTransactionHandler handler : getHandlers())
+ {
+ handler.modifyingObject(this, object);
+ }
+
register(dirtyObjects, object);
}
@@ -237,10 +281,10 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
}
}
- private List<CDOPackageImpl> analyzeNewPackages(CDOSessionImpl session)
+ private List<CDOPackage> analyzeNewPackages(CDOSessionImpl session)
{
Set<EPackage> ePackages = new HashSet<EPackage>();
- for (InternalCDOObject object : newObjects.values())
+ for (CDOObject object : newObjects.values())
{
ePackages.add(object.eClass().getEPackage());
}
@@ -249,7 +293,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
ePackages = new EMFPackageClosure().calculate(ePackages);
CDOSessionPackageManager packageManager = session.getPackageManager();
- List<CDOPackageImpl> cdoPackages = new ArrayList<CDOPackageImpl>();
+ List<CDOPackage> cdoPackages = new ArrayList<CDOPackage>();
for (EPackage ePackage : ePackages)
{
CDOPackageImpl cdoPackage = ModelUtil.getCDOPackage(ePackage, packageManager);
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionRequest.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionRequest.java
index 0e140d9..3ce55f0 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionRequest.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionRequest.java
@@ -10,7 +10,8 @@
**************************************************************************/
package org.eclipse.emf.internal.cdo.protocol;
-import org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl;
+import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.internal.protocol.CDOIDImpl;
import org.eclipse.emf.cdo.internal.protocol.CDOIDRangeImpl;
import org.eclipse.emf.cdo.internal.protocol.model.CDOPackageImpl;
@@ -18,17 +19,18 @@ import org.eclipse.emf.cdo.internal.protocol.revision.CDORevisionImpl;
import org.eclipse.emf.cdo.protocol.CDOID;
import org.eclipse.emf.cdo.protocol.CDOIDRange;
import org.eclipse.emf.cdo.protocol.CDOProtocolConstants;
+import org.eclipse.emf.cdo.protocol.model.CDOPackage;
import org.eclipse.emf.cdo.protocol.revision.CDORevision;
+import org.eclipse.emf.internal.cdo.CDOTransactionImpl;
+import org.eclipse.emf.internal.cdo.InternalCDOObject;
+import org.eclipse.emf.internal.cdo.bundle.OM;
+
import org.eclipse.net4j.IChannel;
import org.eclipse.net4j.internal.util.om.trace.ContextTracer;
import org.eclipse.net4j.util.io.ExtendedDataInputStream;
import org.eclipse.net4j.util.io.ExtendedDataOutputStream;
-import org.eclipse.emf.internal.cdo.CDOTransactionImpl;
-import org.eclipse.emf.internal.cdo.InternalCDOObject;
-import org.eclipse.emf.internal.cdo.bundle.OM;
-
import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
@@ -67,22 +69,22 @@ public class CommitTransactionRequest extends CDOClientRequest<CommitTransaction
private void writeNewPackages(ExtendedDataOutputStream out) throws IOException
{
- List<CDOPackageImpl> newPackages = transaction.getNewPackages();
+ List<CDOPackage> newPackages = transaction.getNewPackages();
if (PROTOCOL.isEnabled())
{
PROTOCOL.format("Writing {0} new packages", newPackages.size());
}
out.writeInt(newPackages.size());
- for (CDOPackageImpl newPackage : newPackages)
+ for (CDOPackage newPackage : newPackages)
{
- newPackage.write(out);
+ ((CDOPackageImpl)newPackage).write(out);
}
}
private void writeNewResources(ExtendedDataOutputStream out) throws IOException
{
- Collection<CDOResourceImpl> newResources = transaction.getNewResources().values();
+ Collection<CDOResource> newResources = transaction.getNewResources().values();
if (PROTOCOL.isEnabled())
{
PROTOCOL.format("Writing {0} new resources", newResources.size());
@@ -93,7 +95,7 @@ public class CommitTransactionRequest extends CDOClientRequest<CommitTransaction
private void writeNewObjects(ExtendedDataOutputStream out) throws IOException
{
- Collection<InternalCDOObject> newObjects = transaction.getNewObjects().values();
+ Collection<CDOObject> newObjects = transaction.getNewObjects().values();
if (PROTOCOL.isEnabled())
{
PROTOCOL.format("Writing {0} new objects", newObjects.size());
@@ -104,7 +106,7 @@ public class CommitTransactionRequest extends CDOClientRequest<CommitTransaction
private void writeDirtyObjects(ExtendedDataOutputStream out) throws IOException
{
- Collection<InternalCDOObject> dirtyObjects = transaction.getDirtyObjects().values();
+ Collection<CDOObject> dirtyObjects = transaction.getDirtyObjects().values();
if (PROTOCOL.isEnabled())
{
PROTOCOL.format("Writing {0} dirty objects", dirtyObjects.size());
@@ -130,12 +132,12 @@ public class CommitTransactionRequest extends CDOClientRequest<CommitTransaction
long timeStamp = in.readLong();
CommitTransactionResult result = new CommitTransactionResult(timeStamp);
- List<CDOPackageImpl> newPackages = transaction.getNewPackages();
- for (CDOPackageImpl newPackage : newPackages)
+ List<CDOPackage> newPackages = transaction.getNewPackages();
+ for (CDOPackage newPackage : newPackages)
{
CDOIDRange oldRange = newPackage.getMetaIDRange();
CDOIDRange newRange = CDOIDRangeImpl.read(in);
- newPackage.setMetaIDRange(newRange);
+ ((CDOPackageImpl)newPackage).setMetaIDRange(newRange);
for (long i = 0; i < oldRange.getCount(); i++)
{
CDOID oldID = oldRange.get(i);
diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/internal/util/event/Notifier.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/internal/util/event/Notifier.java
index c6bb4fa..1f43034 100644
--- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/internal/util/event/Notifier.java
+++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/internal/util/event/Notifier.java
@@ -23,6 +23,9 @@ import java.util.List;
*/
public class Notifier implements INotifier.Introspection
{
+ /**
+ * TODO Optimize by storing an array
+ */
private List<IListener> listeners = new ArrayList<IListener>(0);
public Notifier()