Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/internal/workspace/CDOWorkspaceImpl.java')
-rw-r--r--plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/internal/workspace/CDOWorkspaceImpl.java310
1 files changed, 217 insertions, 93 deletions
diff --git a/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/internal/workspace/CDOWorkspaceImpl.java b/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/internal/workspace/CDOWorkspaceImpl.java
index 190487f9c7..0a7bfa8d29 100644
--- a/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/internal/workspace/CDOWorkspaceImpl.java
+++ b/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/internal/workspace/CDOWorkspaceImpl.java
@@ -27,6 +27,7 @@ import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
import org.eclipse.emf.cdo.common.revision.CDORevisionManager;
import org.eclipse.emf.cdo.common.revision.CDORevisionProvider;
import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.internal.server.Repository;
import org.eclipse.emf.cdo.net4j.CDONet4jSessionConfiguration;
import org.eclipse.emf.cdo.net4j.CDONet4jUtil;
@@ -46,7 +47,9 @@ import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranch;
import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
import org.eclipse.emf.cdo.spi.common.revision.CDOIDMapper;
+import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.ManagedRevisionProvider;
import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.spi.server.InternalStore;
import org.eclipse.emf.cdo.spi.workspace.InternalCDOWorkspace;
@@ -54,6 +57,7 @@ import org.eclipse.emf.cdo.spi.workspace.InternalCDOWorkspaceBase;
import org.eclipse.emf.cdo.transaction.CDOCommitContext;
import org.eclipse.emf.cdo.transaction.CDODefaultTransactionHandler1;
import org.eclipse.emf.cdo.transaction.CDODefaultTransactionHandler2;
+import org.eclipse.emf.cdo.transaction.CDODefaultTransactionHandler3;
import org.eclipse.emf.cdo.transaction.CDOMerger;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.transaction.CDOTransactionFinishedEvent;
@@ -61,7 +65,6 @@ import org.eclipse.emf.cdo.util.CommitException;
import org.eclipse.emf.cdo.util.ReadOnlyException;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.cdo.workspace.CDOWorkspace;
-import org.eclipse.emf.cdo.workspace.CDOWorkspaceUtil;
import org.eclipse.net4j.Net4jUtil;
import org.eclipse.net4j.jvm.IJVMAcceptor;
@@ -174,7 +177,7 @@ public class CDOWorkspaceImpl extends Notifier implements InternalCDOWorkspace
private void setDirtyFromBase()
{
- setDirty(!CDOWorkspaceUtil.getWorkspaceBase2(base).isEmpty());
+ setDirty(!base.isEmpty());
}
protected void checkout()
@@ -297,6 +300,7 @@ public class CDOWorkspaceImpl extends Notifier implements InternalCDOWorkspace
{
CDOTransaction transaction = getLocalSession().openTransaction();
initView(transaction);
+ initTransaction(transaction);
return (InternalCDOTransaction)transaction;
}
@@ -304,9 +308,79 @@ public class CDOWorkspaceImpl extends Notifier implements InternalCDOWorkspace
{
CDOTransaction transaction = getLocalSession().openTransaction(resourceSet);
initView(transaction);
+ initTransaction(transaction);
return (InternalCDOTransaction)transaction;
}
+ protected void initView(CDOView view)
+ {
+ synchronized (views)
+ {
+ views.add((InternalCDOView)view);
+ }
+
+ view.addListener(new ViewAdapter());
+
+ if (view instanceof CDOTransaction)
+ {
+ if (fixed)
+ {
+ throw new ReadOnlyException("Workspace is fixed");
+ }
+
+ if (idGenerationLocation != IDGenerationLocation.CLIENT)
+ {
+ CDOTransaction transaction = (CDOTransaction)view;
+ transaction.addTransactionHandler(new CDODefaultTransactionHandler1()
+ {
+ @Override
+ public void attachingObject(CDOTransaction transaction, CDOObject object)
+ {
+ throw new IllegalStateException("Attaching new objects is only supported for IDGenerationLocation.CLIENT");
+ }
+ });
+ }
+ }
+ }
+
+ protected void initTransaction(CDOTransaction transaction)
+ {
+ transaction.addTransactionHandler(new CDODefaultTransactionHandler2()
+ {
+ @Override
+ public void committedTransaction(CDOTransaction transaction, CDOCommitContext commitContext)
+ {
+ InternalCDOTransaction tx = (InternalCDOTransaction)transaction;
+ Set<CDOID> dirtyObjects = tx.getDirtyObjects().keySet();
+ Set<CDOID> detachedObjects = tx.getDetachedObjects().keySet();
+ for (InternalCDORevision revision : tx.getCleanRevisions().values())
+ {
+ CDOID id = revision.getID();
+ boolean isDetached = detachedObjects.contains(id);
+
+ if (isDetached && base.isAddedObject(id))
+ {
+ base.deregisterObject(id);
+ }
+
+ if (dirtyObjects.contains(id) || isDetached)
+ {
+ base.registerChangedOrDetachedObject(revision);
+ }
+ }
+
+ // Don't use keySet() because only the values() are ID-mapped!
+ for (CDOObject object : tx.getNewObjects().values())
+ {
+ CDOID id = object.cdoID();
+ base.registerAddedObject(id);
+ }
+
+ setDirtyFromBase();
+ }
+ });
+ }
+
public InternalCDOTransaction update(CDOMerger merger)
{
return merge(merger, branchPath);
@@ -319,55 +393,137 @@ public class CDOWorkspaceImpl extends Notifier implements InternalCDOWorkspace
public InternalCDOTransaction merge(CDOMerger merger, String branchPath, long timeStamp)
{
- InternalCDOSession remoteSession = openRemoteSession();
-
- try
+ final InternalCDOSession remoteSession = openRemoteSession();
+ if (timeStamp == CDOBranchPoint.UNSPECIFIED_DATE)
{
- InternalCDOBranchManager branchManager = remoteSession.getBranchManager();
- CDOBranchPoint basePoint = branchManager.getBranch(branchPath).getPoint(this.timeStamp);
- CDOBranchPoint remotePoint = branchManager.getBranch(branchPath).getPoint(timeStamp);
+ timeStamp = remoteSession.getLastUpdateTime();
+ }
- CDOBranchPointRange range = CDOBranchUtil.createRange(basePoint, remotePoint);
- CDOChangeSetData remoteData = remoteSession.getSessionProtocol().loadChangeSets(range)[0];
+ final long newTimeStamp = timeStamp;
- CDOChangeSetData localData = getLocalChanges();
- if (!localData.isEmpty())
- {
- CDOChangeSet localChanges = CDORevisionUtil.createChangeSet(basePoint, null, localData);
- CDOChangeSet remoteChanges = CDORevisionUtil.createChangeSet(basePoint, remotePoint, remoteData);
- remoteData = merger.merge(localChanges, remoteChanges);
- }
+ final InternalCDOBranchManager branchManager = remoteSession.getBranchManager();
+ final CDOBranchPoint basePoint = branchManager.getBranch(branchPath).getPoint(this.timeStamp);
+ final CDOBranchPoint remotePoint = branchManager.getBranch(branchPath).getPoint(newTimeStamp);
+
+ final CDOBranchPointRange range = CDOBranchUtil.createRange(basePoint, remotePoint);
+
+ final CDOChangeSetData remoteData = remoteSession.getSessionProtocol().loadChangeSets(range)[0];
+ final CDOChangeSetData localData = getLocalChanges();
+ final CDOChangeSetData result = getMergeResult(merger, basePoint, remotePoint, localData, remoteData);
+
+ final InternalCDOTransaction transaction = (InternalCDOTransaction)getLocalSession().openTransaction();
+ initView(transaction);
- InternalCDOTransaction transaction = openTransaction();
- transaction.addTransactionHandler(new CDODefaultTransactionHandler2()
+ transaction.applyChangeSet(result, new BaseRevisionProvider(), this, null, false);
+ transaction.addTransactionHandler(new CDODefaultTransactionHandler3()
+ {
+ @Override
+ public void committedTransaction(CDOTransaction transaction, CDOCommitContext commitContext, CDOCommitInfo result)
{
- @Override
- public void committedTransaction(CDOTransaction transaction, CDOCommitContext commitContext)
+ try
+ {
+ Set<CDOID> affectedIDs = getAffectedIDs(commitContext, remoteData);
+
+ CDORevisionProvider local = CDOWorkspaceImpl.this;
+ CDORevisionProvider remote = new ManagedRevisionProvider(remoteSession.getRevisionManager(), remotePoint);
+
+ updateBase(affectedIDs, local, remote);
+ setTimeStamp(newTimeStamp);
+ }
+ finally
{
- clearBase();
+ LifecycleUtil.deactivate(remoteSession);
}
- });
+ }
- transaction.applyChangeSet(remoteData, new CDORevisionProvider()
+ private void updateBase(Set<CDOID> affectedIDs, CDORevisionProvider local, CDORevisionProvider remote)
{
- public CDORevision getRevision(CDOID id)
+ for (CDOID id : affectedIDs)
{
- CDORevision revision = base.getRevision(id);
- if (revision == null)
+ CDORevision localRevision = getRevision(id, local);
+ CDORevision remoteRevision = getRevision(id, remote);
+ if (localRevision == null)
+ {
+ if (remoteRevision == null)
+ {
+ // Unchanged
+ base.deregisterObject(id);
+ }
+ else
+ {
+ // Detached
+ base.registerChangedOrDetachedObject((InternalCDORevision)remoteRevision);
+ }
+ }
+ else
{
- revision = CDOWorkspaceImpl.this.getRevision(id);
+ if (remoteRevision == null)
+ {
+ // Added
+ base.registerAddedObject(id);
+ }
+ else
+ {
+ CDORevisionDelta delta = localRevision.compare(remoteRevision);
+ if (delta.isEmpty())
+ {
+ // Unchanged
+ base.deregisterObject(id);
+ }
+ else
+ {
+ // Changed
+ base.registerChangedOrDetachedObject((InternalCDORevision)remoteRevision);
+ }
+ }
}
+ }
+ }
- return revision;
+ private Set<CDOID> getAffectedIDs(CDOCommitContext commitContext, final CDOChangeSetData remoteData)
+ {
+ Set<CDOID> affectedIDs = new HashSet<CDOID>();
+
+ // Base IDs
+ affectedIDs.addAll(base.getIDs());
+
+ // Remote IDs
+ affectedIDs.addAll(remoteData.getChangeKinds().keySet());
+
+ // Local IDs
+ affectedIDs.addAll(commitContext.getNewObjects().keySet());
+ affectedIDs.addAll(commitContext.getDirtyObjects().keySet());
+ affectedIDs.addAll(commitContext.getDetachedObjects().keySet());
+
+ return affectedIDs;
+ }
+
+ private CDORevision getRevision(CDOID id, CDORevisionProvider revisionProvider)
+ {
+ CDORevision revision = revisionProvider.getRevision(id);
+ if (revision instanceof DetachedCDORevision)
+ {
+ revision = null;
}
- }, this, null, false);
- return transaction;
- }
- finally
+ return revision;
+ }
+ });
+
+ return transaction;
+ }
+
+ private CDOChangeSetData getMergeResult(CDOMerger merger, CDOBranchPoint basePoint, CDOBranchPoint remotePoint,
+ CDOChangeSetData localData, CDOChangeSetData remoteData)
+ {
+ if (localData.isEmpty())
{
- LifecycleUtil.deactivate(remoteSession);
+ return remoteData;
}
+
+ CDOChangeSet localChanges = CDORevisionUtil.createChangeSet(basePoint, null, localData);
+ CDOChangeSet remoteChanges = CDORevisionUtil.createChangeSet(basePoint, remotePoint, remoteData);
+ return merger.merge(localChanges, remoteChanges);
}
public void revert()
@@ -411,23 +567,11 @@ public class CDOWorkspaceImpl extends Notifier implements InternalCDOWorkspace
throw new CommitException(ex);
}
- // Attaching new objects is only supported for IDGenerationLocation.CLIENT
- // CDOIDMapper idMapper = getIDMapper(transaction, result.getIDMappings());
-
transaction.setCommitComment(comment);
CDOCommitInfo info = transaction.commit();
- // Attaching new objects is only supported for IDGenerationLocation.CLIENT
- // if (idMapper != null)
- // {
- // adjustLocalIDs(idMapper, result.getAdjustedObjects());
- // }
-
clearBase();
-
- timeStamp = info.getTimeStamp();
- saveProperties();
-
+ setTimeStamp(info.getTimeStamp());
return info;
}
finally
@@ -704,52 +848,6 @@ public class CDOWorkspaceImpl extends Notifier implements InternalCDOWorkspace
}
}
- protected void initView(CDOView view)
- {
- synchronized (views)
- {
- views.add((InternalCDOView)view);
- }
-
- view.addListener(new ViewAdapter());
-
- if (view instanceof CDOTransaction)
- {
- if (fixed)
- {
- throw new ReadOnlyException("Workspace is fixed");
- }
-
- CDOTransaction transaction = (CDOTransaction)view;
- transaction.addTransactionHandler(new CDODefaultTransactionHandler2()
- {
- @Override
- public void committedTransaction(CDOTransaction transaction, CDOCommitContext commitContext)
- {
- CDOWorkspaceImpl.this.committedTransaction(transaction, commitContext);
- }
- });
-
- if (idGenerationLocation != IDGenerationLocation.CLIENT)
- {
- transaction.addTransactionHandler(new CDODefaultTransactionHandler1()
- {
- @Override
- public void attachingObject(CDOTransaction transaction, CDOObject object)
- {
- throw new IllegalStateException("Attaching new objects is only supported for IDGenerationLocation.CLIENT");
- }
- });
- }
- }
- }
-
- protected void committedTransaction(CDOTransaction transaction, CDOCommitContext commitContext)
- {
- base.updateAfterCommit(transaction);
- setDirtyFromBase();
- }
-
protected InternalCDOSession openRemoteSession()
{
CDOSessionConfiguration configuration = remoteSessionConfigurationFactory.createSessionConfiguration();
@@ -772,6 +870,15 @@ public class CDOWorkspaceImpl extends Notifier implements InternalCDOWorkspace
return session;
}
+ protected void setTimeStamp(long timeStamp)
+ {
+ Map<String, String> props = new HashMap<String, String>();
+ props.put(PROP_TIME_STAMP, String.valueOf(timeStamp));
+ localRepository.getStore().setPersistentProperties(props);
+
+ this.timeStamp = timeStamp;
+ }
+
protected void saveProperties()
{
Map<String, String> props = new HashMap<String, String>();
@@ -793,6 +900,23 @@ public class CDOWorkspaceImpl extends Notifier implements InternalCDOWorkspace
/**
* @author Eike Stepper
*/
+ private class BaseRevisionProvider implements CDORevisionProvider
+ {
+ public CDORevision getRevision(CDOID id)
+ {
+ CDORevision revision = base.getRevision(id);
+ if (revision == null)
+ {
+ revision = CDOWorkspaceImpl.this.getRevision(id);
+ }
+
+ return revision;
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
public final class ViewAdapter extends LifecycleEventAdapter
{
public ViewAdapter()

Back to the top