diff options
Diffstat (limited to 'plugins/org.eclipse.emf.cdo/src')
18 files changed, 438 insertions, 264 deletions
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOLock.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOLock.java index 9393edbadf..84a1b1f909 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOLock.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOLock.java @@ -18,7 +18,7 @@ import org.eclipse.net4j.util.concurrent.RWLockManager; import java.util.concurrent.locks.Lock; /** - * TODO Simon: JavaDoc + * Once object got lock, it will not go in conflict mode or cannot be changed. * * @author Simon McDuff * @since 2.0 diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java index f43e9f4bf3..9aad67fadd 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java @@ -271,6 +271,9 @@ public interface CDOView extends CDOCommonView, INotifier, IOptionsContainer */ public int reload(CDOObject... objects); + /** + * Locks the given objects. Once the objects are locked, they will not be changed remotely or go in conflict state. + */ public void lockObjects(Collection<? extends CDOObject> objects, RWLockManager.LockType lockType, long timeout) throws InterruptedException; diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOMetaWrapper.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOMetaWrapper.java index e91ce718d1..19f6868a34 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOMetaWrapper.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOMetaWrapper.java @@ -55,6 +55,7 @@ public class CDOMetaWrapper extends CDOObjectWrapper throw new UnsupportedOperationException(); } + @Override public EClass eClass() { throw new UnsupportedOperationException(); diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java index 7f3722c62d..dcb23d2963 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java @@ -297,6 +297,35 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent /** * @since 2.0 */ + public InternalCDORevision readNoLoad(InternalCDOObject object) + { + ReentrantLock lock = lockView(object.cdoView()); + + try + { + switch (object.cdoState()) + { + case TRANSIENT: + case PREPARED: + case NEW: + case CONFLICT: + case INVALID_CONFLICT: + case INVALID: + case PROXY: + return null; + } + + return object.cdoRevision(); + } + finally + { + unlockView(lock); + } + } + + /** + * @since 2.0 + */ public void write(InternalCDOObject object) { write(object, null); diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/FailOverStrategyInjector.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/FailOverStrategyInjector.java index 4f87b4a266..c7280d31aa 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/FailOverStrategyInjector.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/FailOverStrategyInjector.java @@ -52,22 +52,22 @@ public class FailOverStrategyInjector implements IElementProcessor int pos = description.indexOf(SCHEME_SEPARATOR); if (pos == -1) { - throw new IllegalArgumentException(MessageFormat.format(INVALID_URI_MESSAGE, description, - Messages.getString("FailOverStrategyInjector.0"))); //$NON-NLS-1$ + throw new IllegalArgumentException(MessageFormat.format(INVALID_URI_MESSAGE, description, Messages + .getString("FailOverStrategyInjector.0"))); //$NON-NLS-1$ } String factoryType = description.substring(0, pos); if (StringUtil.isEmpty(factoryType)) { - throw new IllegalArgumentException(MessageFormat.format(INVALID_URI_MESSAGE, description, - Messages.getString("FailOverStrategyInjector.1"))); //$NON-NLS-1$ + throw new IllegalArgumentException(MessageFormat.format(INVALID_URI_MESSAGE, description, Messages + .getString("FailOverStrategyInjector.1"))); //$NON-NLS-1$ } String connectorDescription = description.substring(pos + SCHEME_SEPARATOR.length()); if (StringUtil.isEmpty(connectorDescription)) { - throw new IllegalArgumentException(MessageFormat.format(INVALID_URI_MESSAGE, description, - Messages.getString("FailOverStrategyInjector.2"))); //$NON-NLS-1$ + throw new IllegalArgumentException(MessageFormat.format(INVALID_URI_MESSAGE, description, Messages + .getString("FailOverStrategyInjector.2"))); //$NON-NLS-1$ } pos = connectorDescription.indexOf('?'); diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/protocol/AbstractSyncRevisionsRequest.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/protocol/AbstractSyncRevisionsRequest.java new file mode 100644 index 0000000000..8f447ed197 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/protocol/AbstractSyncRevisionsRequest.java @@ -0,0 +1,138 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others. + * 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: + * Simon McDuff - initial API and implementation + * Eike Stepper - maintenance + **************************************************************************/ +package org.eclipse.emf.internal.cdo.net4j.protocol; + +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.id.CDOIDAndVersion; +import org.eclipse.emf.cdo.common.id.CDOIDUtil; +import org.eclipse.emf.cdo.common.io.CDODataInput; +import org.eclipse.emf.cdo.common.io.CDODataOutput; +import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.messages.Messages; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; +import org.eclipse.emf.cdo.transaction.CDOTimeStampContext; + +import org.eclipse.emf.internal.cdo.bundle.OM; +import org.eclipse.emf.internal.cdo.session.CDORevisionManagerImpl; +import org.eclipse.emf.internal.cdo.transaction.CDOTimeStampContextImpl; + +import org.eclipse.net4j.util.om.trace.ContextTracer; + +import java.io.IOException; +import java.text.MessageFormat; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +/** + * @author Simon McDuff + * @since 2.0 + */ +public abstract class AbstractSyncRevisionsRequest extends CDOClientRequest<Collection<CDOTimeStampContext>> +{ + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, AbstractSyncRevisionsRequest.class); + + protected Map<CDOID, CDOIDAndVersion> idAndVersions; + + protected int referenceChunk; + + public AbstractSyncRevisionsRequest(CDOClientProtocol protocol, short signalID, + Map<CDOID, CDOIDAndVersion> idAndVersions, int referenceChunk) + { + super(protocol, signalID); + this.idAndVersions = idAndVersions; + this.referenceChunk = referenceChunk; + } + + @Override + protected void requesting(CDODataOutput out) throws IOException + { + if (TRACER.isEnabled()) + { + TRACER.trace("Synchronization " + idAndVersions.size() + " objects"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + out.writeInt(referenceChunk); + out.writeInt(idAndVersions.size()); + for (CDOIDAndVersion idAndVersion : idAndVersions.values()) + { + out.writeCDOIDAndVersion(idAndVersion); + } + } + + @Override + protected Collection<CDOTimeStampContext> confirming(CDODataInput in) throws IOException + { + CDORevisionManagerImpl revisionManager = (CDORevisionManagerImpl)getSession().getRevisionManager(); + TreeMap<Long, CDOTimeStampContext> mapofContext = new TreeMap<Long, CDOTimeStampContext>(); + + int size = in.readInt(); + for (int i = 0; i < size; i++) + { + CDORevision revision = in.readCDORevision(); + long revised = in.readLong(); + + CDOIDAndVersion idAndVersion = idAndVersions.get(revision.getID()); + if (idAndVersion == null) + { + throw new IllegalStateException(MessageFormat.format( + Messages.getString("SyncRevisionsRequest.2"), revision.getID())); //$NON-NLS-1$ + } + + Set<CDOIDAndVersion> dirtyObjects = getMap(mapofContext, revised).getDirtyObjects(); + dirtyObjects.add(CDOIDUtil.createIDAndVersion(idAndVersion.getID(), idAndVersion.getVersion())); + revisionManager.addCachedRevision((InternalCDORevision)revision); + } + + if (TRACER.isEnabled()) + { + TRACER.trace("Synchronization received " + size + " dirty objects"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + size = in.readInt(); + for (int i = 0; i < size; i++) + { + CDOID id = in.readCDOID(); + long revised = in.readLong(); + + Collection<CDOID> detachedObjects = getMap(mapofContext, revised).getDetachedObjects(); + detachedObjects.add(id); + } + + for (CDOTimeStampContext timestampContext : mapofContext.values()) + { + Set<CDOIDAndVersion> dirtyObjects = timestampContext.getDirtyObjects(); + Collection<CDOID> detachedObjects = timestampContext.getDetachedObjects(); + + dirtyObjects = Collections.unmodifiableSet(dirtyObjects); + detachedObjects = Collections.unmodifiableCollection(detachedObjects); + + ((CDOTimeStampContextImpl)timestampContext).setDirtyObjects(dirtyObjects); + ((CDOTimeStampContextImpl)timestampContext).setDetachedObjects(detachedObjects); + } + return Collections.unmodifiableCollection(mapofContext.values()); + } + + private CDOTimeStampContext getMap(Map<Long, CDOTimeStampContext> mapOfContext, long timestamp) + { + CDOTimeStampContext result = mapOfContext.get(timestamp); + if (result == null) + { + result = new CDOTimeStampContextImpl(timestamp); + mapOfContext.put(timestamp, result); + } + + return result; + } +} diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/protocol/CDOClientProtocol.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/protocol/CDOClientProtocol.java index 5dab60355d..7cd1517158 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/protocol/CDOClientProtocol.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/protocol/CDOClientProtocol.java @@ -167,7 +167,7 @@ public class CDOClientProtocol extends CDOProtocolImpl implements CDOSessionProt } } - public void lockObjects(CDOView view, Collection<? extends CDOObject> objects, long timeout, LockType lockType) + public void lockObjects(CDOView view, Map<CDOID, CDOIDAndVersion> objects, long timeout, LockType lockType) throws InterruptedException { InterruptedException interruptedException = null; @@ -175,7 +175,8 @@ public class CDOClientProtocol extends CDOProtocolImpl implements CDOSessionProt try { - new LockObjectsRequest(this, view, objects, timeout, lockType).send(); + new LockObjectsRequest(this, view, objects, view.getSession().options().getCollectionLoadingPolicy() + .getInitialChunkSize(), timeout, lockType).send(); } catch (RemoteException ex) { diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/protocol/CommitNotificationIndication.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/protocol/CommitNotificationIndication.java index 02e39744e0..2b44719737 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/protocol/CommitNotificationIndication.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/protocol/CommitNotificationIndication.java @@ -55,7 +55,7 @@ public class CommitNotificationIndication extends CDOClientIndication } CDOPackageUnit[] packageUnits = in.readCDOPackageUnits(null); - InternalCDOPackageRegistry packageRegistry = (InternalCDOPackageRegistry)getSession().getPackageRegistry(); + InternalCDOPackageRegistry packageRegistry = getSession().getPackageRegistry(); for (int i = 0; i < packageUnits.length; i++) { packageRegistry.putPackageUnit((InternalCDOPackageUnit)packageUnits[i]); diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/protocol/LockObjectsRequest.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/protocol/LockObjectsRequest.java index 2002179965..95532f4bcd 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/protocol/LockObjectsRequest.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/protocol/LockObjectsRequest.java @@ -10,10 +10,12 @@ **************************************************************************/ package org.eclipse.emf.internal.cdo.net4j.protocol; -import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.id.CDOIDAndVersion; import org.eclipse.emf.cdo.common.io.CDODataInput; import org.eclipse.emf.cdo.common.io.CDODataOutput; import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; +import org.eclipse.emf.cdo.transaction.CDOTimeStampContext; import org.eclipse.emf.cdo.view.CDOView; import org.eclipse.emf.internal.cdo.bundle.OM; @@ -21,13 +23,18 @@ import org.eclipse.emf.internal.cdo.bundle.OM; import org.eclipse.net4j.util.concurrent.RWLockManager; import org.eclipse.net4j.util.om.trace.ContextTracer; +import org.eclipse.emf.spi.cdo.InternalCDOObject; +import org.eclipse.emf.spi.cdo.InternalCDOView; + import java.io.IOException; import java.util.Collection; +import java.util.HashSet; +import java.util.Map; /** * @author Simon McDuff */ -public class LockObjectsRequest extends CDOClientRequest<Object> +public class LockObjectsRequest extends AbstractSyncRevisionsRequest { private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, LockObjectsRequest.class); @@ -35,16 +42,14 @@ public class LockObjectsRequest extends CDOClientRequest<Object> private RWLockManager.LockType lockType; - private Collection<? extends CDOObject> objects; - private long timeout; - public LockObjectsRequest(CDOClientProtocol protocol, CDOView view, Collection<? extends CDOObject> objects, - long timeout, RWLockManager.LockType lockType) + public LockObjectsRequest(CDOClientProtocol protocol, CDOView view, Map<CDOID, CDOIDAndVersion> idAndVersions, + int referenceChunk, long timeout, RWLockManager.LockType lockType) { - super(protocol, CDOProtocolConstants.SIGNAL_LOCK_OBJECTS); + super(protocol, CDOProtocolConstants.SIGNAL_LOCK_OBJECTS, idAndVersions, referenceChunk); this.view = view; - this.objects = objects; + this.timeout = timeout; this.lockType = lockType; } @@ -52,6 +57,7 @@ public class LockObjectsRequest extends CDOClientRequest<Object> @Override protected void requesting(CDODataOutput out) throws IOException { + super.requesting(out); out.writeInt(view.getViewID()); out.writeCDOLockType(lockType); out.writeLong(timeout); @@ -61,23 +67,20 @@ public class LockObjectsRequest extends CDOClientRequest<Object> TRACER.format("Locking of type {0} requested for view {1} with timeout {2}", //$NON-NLS-1$ lockType == RWLockManager.LockType.READ ? "read" : "write", view.getViewID(), timeout); //$NON-NLS-1$ //$NON-NLS-2$ } - - out.writeInt(objects.size()); - for (CDOObject object : objects) - { - if (TRACER.isEnabled()) - { - TRACER.format("Locking requested for objects {0}", object.cdoID()); //$NON-NLS-1$ - } - - out.writeCDOID(object.cdoID()); - } } @Override - protected Object confirming(CDODataInput in) throws IOException + protected Collection<CDOTimeStampContext> confirming(CDODataInput in) throws IOException { - in.readBoolean(); - return null; + Collection<CDOTimeStampContext> contexts = super.confirming(in); + for (CDOTimeStampContext timestampContext : contexts) + { + getSession().handleUpdateRevision(timestampContext.getTimeStamp(), timestampContext.getDirtyObjects(), + timestampContext.getDetachedObjects()); + ((InternalCDOView)view).handleInvalidationWithoutNotification(timestampContext.getDirtyObjects(), + timestampContext.getDetachedObjects(), new HashSet<InternalCDOObject>(), new HashSet<InternalCDOObject>()); + } + + return contexts; } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/protocol/SyncRevisionsRequest.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/protocol/SyncRevisionsRequest.java index ef75bc11c9..65ed4b1fd1 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/protocol/SyncRevisionsRequest.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/net4j/protocol/SyncRevisionsRequest.java @@ -13,41 +13,22 @@ package org.eclipse.emf.internal.cdo.net4j.protocol; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDAndVersion; -import org.eclipse.emf.cdo.common.id.CDOIDUtil; import org.eclipse.emf.cdo.common.io.CDODataInput; -import org.eclipse.emf.cdo.common.io.CDODataOutput; import org.eclipse.emf.cdo.common.model.CDOPackageUnit; import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; -import org.eclipse.emf.cdo.common.revision.CDORevision; -import org.eclipse.emf.cdo.messages.Messages; -import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; import org.eclipse.emf.cdo.transaction.CDOTimeStampContext; -import org.eclipse.emf.internal.cdo.bundle.OM; -import org.eclipse.emf.internal.cdo.session.CDORevisionManagerImpl; -import org.eclipse.emf.internal.cdo.transaction.CDOTimeStampContextImpl; - -import org.eclipse.net4j.util.om.trace.ContextTracer; - import java.io.IOException; -import java.text.MessageFormat; import java.util.Collection; import java.util.Collections; import java.util.Map; -import java.util.Set; -import java.util.TreeMap; /** * @author Simon McDuff * @since 2.0 */ -public class SyncRevisionsRequest extends CDOClientRequest<Collection<CDOTimeStampContext>> +public class SyncRevisionsRequest extends AbstractSyncRevisionsRequest { - private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, SyncRevisionsRequest.class); - - private Map<CDOID, CDOIDAndVersion> idAndVersions; - - private int referenceChunk; public SyncRevisionsRequest(CDOClientProtocol protocol, Map<CDOID, CDOIDAndVersion> idAndVersions, int referenceChunk) { @@ -57,95 +38,19 @@ public class SyncRevisionsRequest extends CDOClientRequest<Collection<CDOTimeSta public SyncRevisionsRequest(CDOClientProtocol protocol, short signalID, Map<CDOID, CDOIDAndVersion> idAndVersions, int referenceChunk) { - super(protocol, signalID); - this.idAndVersions = idAndVersions; - this.referenceChunk = referenceChunk; - } - - @Override - protected void requesting(CDODataOutput out) throws IOException - { - if (TRACER.isEnabled()) - { - TRACER.trace("Synchronization " + idAndVersions.size() + " objects"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - out.writeInt(referenceChunk); - out.writeInt(idAndVersions.size()); - for (CDOIDAndVersion idAndVersion : idAndVersions.values()) - { - out.writeCDOID(idAndVersion.getID()); - out.writeInt(idAndVersion.getVersion()); - } + super(protocol, signalID, idAndVersions, referenceChunk); } @Override protected Collection<CDOTimeStampContext> confirming(CDODataInput in) throws IOException { - CDORevisionManagerImpl revisionManager = (CDORevisionManagerImpl)getSession().getRevisionManager(); - TreeMap<Long, CDOTimeStampContext> mapofContext = new TreeMap<Long, CDOTimeStampContext>(); - - int size = in.readInt(); - for (int i = 0; i < size; i++) - { - CDORevision revision = in.readCDORevision(); - long revised = in.readLong(); - - CDOIDAndVersion idAndVersion = idAndVersions.get(revision.getID()); - if (idAndVersion == null) - { - throw new IllegalStateException(MessageFormat.format( - Messages.getString("SyncRevisionsRequest.2"), revision.getID())); //$NON-NLS-1$ - } - - Set<CDOIDAndVersion> dirtyObjects = getMap(mapofContext, revised).getDirtyObjects(); - dirtyObjects.add(CDOIDUtil.createIDAndVersion(idAndVersion.getID(), idAndVersion.getVersion())); - revisionManager.addCachedRevision((InternalCDORevision)revision); - } - - if (TRACER.isEnabled()) - { - TRACER.trace("Synchronization received " + size + " dirty objects"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - size = in.readInt(); - for (int i = 0; i < size; i++) - { - CDOID id = in.readCDOID(); - long revised = in.readLong(); - - Collection<CDOID> detachedObjects = getMap(mapofContext, revised).getDetachedObjects(); - detachedObjects.add(id); - } - + Collection<CDOTimeStampContext> contexts = super.confirming(in); Collection<CDOPackageUnit> emptyNewPackageUnits = Collections.emptyList(); - for (CDOTimeStampContext timestampContext : mapofContext.values()) - { - Set<CDOIDAndVersion> dirtyObjects = timestampContext.getDirtyObjects(); - Collection<CDOID> detachedObjects = timestampContext.getDetachedObjects(); - - dirtyObjects = Collections.unmodifiableSet(dirtyObjects); - detachedObjects = Collections.unmodifiableCollection(detachedObjects); - - ((CDOTimeStampContextImpl)timestampContext).setDirtyObjects(dirtyObjects); - ((CDOTimeStampContextImpl)timestampContext).setDetachedObjects(detachedObjects); - - getSession().handleSyncResponse(timestampContext.getTimeStamp(), emptyNewPackageUnits, dirtyObjects, - detachedObjects); - } - - return Collections.unmodifiableCollection(mapofContext.values()); - } - - private CDOTimeStampContext getMap(Map<Long, CDOTimeStampContext> mapOfContext, long timestamp) - { - CDOTimeStampContext result = mapOfContext.get(timestamp); - if (result == null) + for (CDOTimeStampContext timestampContext : contexts) { - result = new CDOTimeStampContextImpl(timestamp); - mapOfContext.put(timestamp, result); + getSession().handleSyncResponse(timestampContext.getTimeStamp(), emptyNewPackageUnits, + timestampContext.getDirtyObjects(), timestampContext.getDetachedObjects()); } - - return result; + return contexts; } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/query/CDOQueryImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/query/CDOQueryImpl.java index 9616aa2ce5..b608377ec0 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/query/CDOQueryImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/query/CDOQueryImpl.java @@ -34,6 +34,7 @@ import java.util.Map.Entry; public class CDOQueryImpl extends CDOQueryInfoImpl implements CDOQuery { private static final String OBJECT_NOT_PERSISTED_MESSAGE = Messages.getString("CDOQueryImpl.0"); //$NON-NLS-1$ + private InternalCDOView view; public CDOQueryImpl(InternalCDOView view, String queryLanguage, String queryString) diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDORevisionManagerImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDORevisionManagerImpl.java index 69d6ede7e6..d2022f9576 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDORevisionManagerImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDORevisionManagerImpl.java @@ -19,12 +19,17 @@ import org.eclipse.emf.cdo.session.CDORevisionManager; import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; import org.eclipse.emf.cdo.view.CDOFetchRuleManager; +import org.eclipse.net4j.util.WrappedException; +import org.eclipse.net4j.util.concurrent.RWLockManager; +import org.eclipse.net4j.util.concurrent.RWLockManager.LockType; + import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.spi.cdo.InternalCDOSession; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Set; /** * @author Eike Stepper @@ -35,6 +40,10 @@ public class CDORevisionManagerImpl extends CDORevisionResolverImpl implements C private CDOFetchRuleManager ruleManager = CDOFetchRuleManager.NOOP; + private RWLockManager<CDORevisionManager, Object> lockmanager = new RWLockManager<CDORevisionManager, Object>(); + + private Set<CDORevisionManagerImpl> singletonCollection = Collections.singleton(this); + /** * @since 2.0 */ @@ -120,4 +129,24 @@ public class CDORevisionManagerImpl extends CDORevisionResolverImpl implements C { return session.getSessionProtocol().loadRevisionsByTime(ids, referenceChunk, timeStamp); } + + @Override + protected void acquireAtomicRequestLock(Object key) + { + try + { + lockmanager.lock(LockType.WRITE, key, this, RWLockManager.WAIT); + } + catch (InterruptedException ex) + { + throw WrappedException.wrap(ex); + } + + } + + @Override + protected void releaseAtomicRequestLock(Object key) + { + lockmanager.unlock(LockType.WRITE, key, singletonCollection); + } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java index 7fbc8859e2..acfd7f689b 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java @@ -38,7 +38,6 @@ import org.eclipse.emf.cdo.session.CDOSession; import org.eclipse.emf.cdo.session.CDOSessionInvalidationEvent; import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry; import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit; -import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; import org.eclipse.emf.cdo.transaction.CDOTimeStampContext; import org.eclipse.emf.cdo.util.CDOUtil; import org.eclipse.emf.cdo.view.CDOView; @@ -68,7 +67,6 @@ import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EcorePackage; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; -import org.eclipse.emf.spi.cdo.InternalCDOObject; import org.eclipse.emf.spi.cdo.InternalCDORemoteSessionManager; import org.eclipse.emf.spi.cdo.InternalCDOSession; import org.eclipse.emf.spi.cdo.InternalCDOTransaction; @@ -82,6 +80,7 @@ import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; import java.text.MessageFormat; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -406,103 +405,119 @@ public abstract class CDOSessionImpl extends Container<CDOView> implements Inter private void handleCommitNotification(final long timeStamp, final Collection<CDOPackageUnit> newPackageUnits, Set<CDOIDAndVersion> dirtyOIDs, final Collection<CDOID> detachedObjects, final Collection<CDORevisionDelta> deltas, InternalCDOView excludedView, final boolean passiveUpdate, - boolean async) + final boolean async) { - if (passiveUpdate) + try { - updateRevisionForRemoteChanges(timeStamp, dirtyOIDs, detachedObjects, excludedView); - } + if (passiveUpdate) + { + updateRevisionForRemoteChanges(timeStamp, dirtyOIDs, detachedObjects, excludedView); + } - final Set<CDOIDAndVersion> finalDirtyOIDs = Collections.unmodifiableSet(dirtyOIDs); - final Collection<CDOID> finalDetachedObjects = Collections.unmodifiableCollection(detachedObjects); - final boolean skipChangeSubscription = (deltas == null || deltas.size() <= 0) - && (detachedObjects == null || detachedObjects.size() <= 0); + final Set<CDOIDAndVersion> finalDirtyOIDs = Collections.unmodifiableSet(dirtyOIDs); + final Collection<CDOID> finalDetachedObjects = Collections.unmodifiableCollection(detachedObjects); + final boolean skipChangeSubscription = (deltas == null || deltas.size() <= 0) + && (detachedObjects == null || detachedObjects.size() <= 0); - for (final InternalCDOView view : getViews()) - { - if (view != excludedView) + for (final InternalCDOView view : getViews()) { - Runnable runnable = new Runnable() + if (view != excludedView) { - public void run() + Runnable runnable = new Runnable() { - try + public void run() { - Set<CDOObject> conflicts = null; - if (passiveUpdate) - { - conflicts = view.handleInvalidation(timeStamp, finalDirtyOIDs, finalDetachedObjects); - } - - if (!skipChangeSubscription) + try { - view.handleChangeSubscription(deltas, detachedObjects); + Set<CDOObject> conflicts = null; + if (passiveUpdate) + { + conflicts = view.handleInvalidation(timeStamp, finalDirtyOIDs, finalDetachedObjects); + } + + if (!skipChangeSubscription) + { + view.handleChangeSubscription(deltas, detachedObjects); + } + + if (conflicts != null) + { + ((InternalCDOTransaction)view).handleConflicts(conflicts); + } } - - if (conflicts != null) + catch (RuntimeException ex) { - ((InternalCDOTransaction)view).handleConflicts(conflicts); + if (!async) + { + throw ex; + } + + if (isActive()) + { + OM.LOG.error(ex); + } + else + { + OM.LOG.info("Commit notification arrived while session is inactive"); + } } } - catch (RuntimeException ex) - { - OM.LOG.error(ex); - } - } - }; + }; - if (async) - { - QueueRunner runner = getInvalidationRunner(); - runner.addWork(runnable); - } - else - { - runnable.run(); + if (async) + { + QueueRunner runner = getInvalidationRunner(); + runner.addWork(runnable); + } + else + { + runnable.run(); + } } } } + catch (RuntimeException ex) + { + if (!async) + { + throw ex; + } + + if (isActive()) + { + OM.LOG.error(ex); + } + else + { + OM.LOG.info("Commit notification arrived while session is inactive"); + } + } fireInvalidationEvent(timeStamp, newPackageUnits, dirtyOIDs, detachedObjects, excludedView); } + public void handleUpdateRevision(final long timeStamp, Set<CDOIDAndVersion> dirtyOIDs, + Collection<CDOID> detachedObjects) + { + updateRevisionForRemoteChanges(timeStamp, dirtyOIDs, detachedObjects, null); + } + private void updateRevisionForRemoteChanges(final long timeStamp, Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects, InternalCDOView excludedView) { - // revised is done automatically when postCommit is CDOTransaction.postCommit is happening - // Detached are not revised through postCommit if (excludedView == null || timeStamp == CDORevision.UNSPECIFIED_DATE) { for (CDOIDAndVersion dirtyOID : dirtyOIDs) { CDOID id = dirtyOID.getID(); int version = dirtyOID.getVersion(); - InternalCDORevision revision = revisionManager.getRevisionByVersion(id, 0, version, false); - if (revision != null) - { - if (timeStamp == CDORevision.UNSPECIFIED_DATE) - { - revisionManager.removeCachedRevision(revision.getID(), revision.getVersion()); - } - else - { - revision.setRevised(timeStamp - 1); - } - } + revisionManager.revisedRevisionByVersion(id, version, timeStamp); } } for (CDOID id : detachedObjects) { - InternalCDORevision revision = revisionManager.getRevision(id, 0, false); - if (timeStamp == CDORevision.UNSPECIFIED_DATE) - { - revisionManager.removeCachedRevision(revision.getID(), revision.getVersion()); - } - else if (revision != null) - { - revision.setRevised(timeStamp - 1); - } + revisionManager.revisedRevision(id, timeStamp); } } @@ -742,27 +757,7 @@ public abstract class CDOSessionImpl extends Container<CDOView> implements Inter Map<CDOID, CDOIDAndVersion> uniqueObjects = new HashMap<CDOID, CDOIDAndVersion>(); for (InternalCDOView view : getViews()) { - Map<CDOID, CDORevisionDelta> deltaMap = view instanceof InternalCDOTransaction ? ((InternalCDOTransaction)view) - .getRevisionDeltas() : null; - for (InternalCDOObject internalCDOObject : view.getObjectsArray()) - { - InternalCDORevision cdoRevision = internalCDOObject.cdoRevision(); - CDOID cdoId = internalCDOObject.cdoID(); - if (cdoRevision != null && !cdoId.isTemporary() && !uniqueObjects.containsKey(cdoId)) - { - int version = cdoRevision.getVersion(); - if (deltaMap != null) - { - CDORevisionDelta delta = deltaMap.get(cdoId); - if (delta != null) - { - version = delta.getOriginVersion(); - } - } - - uniqueObjects.put(cdoId, CDOIDUtil.createIDAndVersion(cdoId, version)); - } - } + view.getCDOIDAndVersion(uniqueObjects, Arrays.asList(view.getObjectsArray())); } // Need to add Revision from revisionManager since we do not have all objects in view. diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java index 901728748d..a323935063 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java @@ -285,6 +285,31 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa conflict -= resolved; } + @Override + public void getCDOIDAndVersion(Map<CDOID, CDOIDAndVersion> uniqueObjects, Collection<? extends CDOObject> cdoObjects) + { + Map<CDOID, CDORevisionDelta> deltaMap = getRevisionDeltas(); + + for (CDOObject cdoObject : cdoObjects) + { + CDORevision cdoRevision = CDOStateMachine.INSTANCE.readNoLoad((InternalCDOObject)cdoObject); + CDOID cdoId = cdoObject.cdoID(); + if (cdoRevision != null && !cdoId.isTemporary() && !uniqueObjects.containsKey(cdoId)) + { + int version = cdoRevision.getVersion(); + if (deltaMap != null) + { + CDORevisionDelta delta = deltaMap.get(cdoId); + if (delta != null) + { + version = delta.getOriginVersion(); + } + } + uniqueObjects.put(cdoId, CDOIDUtil.createIDAndVersion(cdoId, version)); + } + } + } + /** * @since 2.0 */ diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java index 9089b9c618..20e8bf313b 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java @@ -278,7 +278,18 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView throws InterruptedException { checkActive(); - session.getSessionProtocol().lockObjects(this, objects, timeout, lockType); + Map<CDOID, CDOIDAndVersion> uniqueObjects = new HashMap<CDOID, CDOIDAndVersion>(); + getCDOIDAndVersion(uniqueObjects, objects); + for (CDOObject object : objects) + { + CDOIDAndVersion idAndVersion = uniqueObjects.get(object.cdoID()); + if (idAndVersion == null) + { + uniqueObjects + .put(object.cdoID(), CDOIDUtil.createIDAndVersion(object.cdoID(), CDORevision.UNSPECIFIED_VERSION)); + } + } + session.getSessionProtocol().lockObjects(this, uniqueObjects, timeout, lockType); } /** @@ -1101,49 +1112,7 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView try { - for (CDOIDAndVersion dirtyOID : dirtyOIDs) - { - InternalCDOObject dirtyObject = null; - // 258831 - Causes deadlock when introduce thread safe mechanisms in State machine. - synchronized (objects) - { - dirtyObject = objects.get(dirtyOID.getID()); - } - - if (dirtyObject != null) - { - CDOStateMachine.INSTANCE.invalidate(dirtyObject, dirtyOID.getVersion()); - dirtyObjects.add(dirtyObject); - if (dirtyObject.cdoConflict()) - { - if (conflicts == null) - { - conflicts = new HashSet<CDOObject>(); - } - - conflicts.add(dirtyObject); - } - } - } - - for (CDOID id : detachedOIDs) - { - InternalCDOObject detachedObject = removeObject(id); - if (detachedObject != null) - { - CDOStateMachine.INSTANCE.detachRemote(detachedObject); - detachedObjects.add(detachedObject); - if (detachedObject.cdoConflict()) - { - if (conflicts == null) - { - conflicts = new HashSet<CDOObject>(); - } - - conflicts.add(detachedObject); - } - } - } + conflicts = handleInvalidationWithoutNotification(dirtyOIDs, detachedOIDs, dirtyObjects, detachedObjects); } finally { @@ -1176,6 +1145,54 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView return conflicts; } + public Set<CDOObject> handleInvalidationWithoutNotification(Set<CDOIDAndVersion> dirtyOIDs, + Collection<CDOID> detachedOIDs, Set<InternalCDOObject> dirtyObjects, Set<InternalCDOObject> detachedObjects) + { + Set<CDOObject> conflicts = null; + for (CDOIDAndVersion dirtyOID : dirtyOIDs) + { + InternalCDOObject dirtyObject = null; + // 258831 - Causes deadlock when introduce thread safe mechanisms in State machine. + synchronized (objects) + { + dirtyObject = objects.get(dirtyOID.getID()); + } + if (dirtyObject != null) + { + CDOStateMachine.INSTANCE.invalidate(dirtyObject, dirtyOID.getVersion()); + dirtyObjects.add(dirtyObject); + if (dirtyObject.cdoConflict()) + { + if (conflicts == null) + { + conflicts = new HashSet<CDOObject>(); + } + + conflicts.add(dirtyObject); + } + } + } + for (CDOID id : detachedOIDs) + { + InternalCDOObject detachedObject = removeObject(id); + if (detachedObject != null) + { + CDOStateMachine.INSTANCE.detachRemote(detachedObject); + detachedObjects.add(detachedObject); + if (detachedObject.cdoConflict()) + { + if (conflicts == null) + { + conflicts = new HashSet<CDOObject>(); + } + + conflicts.add(detachedObject); + } + } + } + return conflicts; + } + /** * @since 2.0 */ @@ -1404,6 +1421,20 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView return getResourceSet(); } + public void getCDOIDAndVersion(Map<CDOID, CDOIDAndVersion> uniqueObjects, Collection<? extends CDOObject> cdoObjects) + { + for (CDOObject internalCDOObject : cdoObjects) + { + CDORevision cdoRevision = CDOStateMachine.INSTANCE.readNoLoad((InternalCDOObject)internalCDOObject); + CDOID cdoId = internalCDOObject.cdoID(); + if (cdoRevision != null && !uniqueObjects.containsKey(cdoId)) + { + int version = cdoRevision.getVersion(); + uniqueObjects.put(cdoId, CDOIDUtil.createIDAndVersion(cdoId, version)); + } + } + } + /** * @since 2.0 */ diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java index 4ed399274e..d331743eee 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java @@ -82,7 +82,7 @@ public interface CDOSessionProtocol extends PackageLoader public boolean cancelQuery(int queryId); - public void lockObjects(CDOView view, Collection<? extends CDOObject> objects, long timeout, LockType lockType) + public void lockObjects(CDOView view, Map<CDOID, CDOIDAndVersion> objects, long timeout, LockType lockType) throws InterruptedException; public void unlockObjects(CDOView view, Collection<? extends CDOObject> objects, LockType lockType); diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java index e6a6296c05..d5b1b3d422 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java @@ -46,4 +46,11 @@ public interface InternalCDOSession extends CDOSession, CDOIDObjectFactory, public void handleSyncResponse(long timestamp, Collection<CDOPackageUnit> newPackageUnits, Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects); + + /** + * In some cases we need to sync without propagating event. Lock is a good example. + */ + public void handleUpdateRevision(final long timeStamp, Set<CDOIDAndVersion> dirtyOIDs, + Collection<CDOID> detachedObjects); + } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java index 483246cb4f..7de9d04cb1 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java @@ -29,6 +29,7 @@ import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.ecore.EObject; import java.util.Collection; +import java.util.Map; import java.util.Set; import java.util.concurrent.locks.ReentrantLock; @@ -64,6 +65,11 @@ public interface InternalCDOView extends CDOView, CDOIDProvider, ILifecycle.Intr public Set<CDOObject> handleInvalidation(long timeStamp, Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedOIDs); + public Set<CDOObject> handleInvalidationWithoutNotification(Set<CDOIDAndVersion> dirtyOIDs, + Collection<CDOID> detachedOIDs, Set<InternalCDOObject> dirtyObjects, Set<InternalCDOObject> detachedObjects); + + public void getCDOIDAndVersion(Map<CDOID, CDOIDAndVersion> uniqueObjects, Collection<? extends CDOObject> cdoObjects); + public void handleChangeSubscription(Collection<CDORevisionDelta> deltas, Collection<CDOID> detachedObjects); public InternalCDOObject[] getObjectsArray(); |