Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2010-02-02 11:39:48 +0000
committerEike Stepper2010-02-02 11:39:48 +0000
commitdc758eb87d5c2f0e802e49de4ca6173d3d94a2c8 (patch)
treeee1091aac506313694923c73871275551cbc714d /plugins/org.eclipse.emf.cdo.common
parent09f6a7f80829204abd2c2bf2511ba3b4e65c81c8 (diff)
downloadcdo-dc758eb87d5c2f0e802e49de4ca6173d3d94a2c8.tar.gz
cdo-dc758eb87d5c2f0e802e49de4ca6173d3d94a2c8.tar.xz
cdo-dc758eb87d5c2f0e802e49de4ca6173d3d94a2c8.zip
[270716] Provide support for branching
https://bugs.eclipse.org/bugs/show_bug.cgi?id=270716
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.common')
-rw-r--r--plugins/org.eclipse.emf.cdo.common/META-INF/MANIFEST.MF20
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonView.java23
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOTimeProvider.java20
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranch.java28
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchCreatedEvent.java24
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchManager.java26
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchPoint.java7
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchTag.java1
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchVersion.java26
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/commit/CDOCommit.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDAndBranch.java25
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDAndVersion.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDAndVersionAndBranch.java21
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDUtil.java19
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/io/CDODataInput.java32
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/io/CDODataOutput.java32
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java89
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevision.java33
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionKey.java23
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionManager.java29
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java78
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/cache/CDORevisionCache.java38
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/cache/CDORevisionCacheFactory.java51
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/cache/CDORevisionCacheUtil.java59
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/cache/InternalCDORevisionCache.java38
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/delta/CDORevisionDelta.java16
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/branch/CDOBranchImpl.java276
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/branch/CDOBranchManagerImpl.java229
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/branch/CDOBranchPointImpl.java83
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/branch/CDOBranchVersionImpl.java71
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/commit/CDOCommitImpl.java42
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDAndBranchImpl.java87
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDAndVersionAndBranchImpl.java80
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDAndVersionImpl.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/io/CDODataInputImpl.java41
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/io/CDODataOutputImpl.java34
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPackageUnitImpl.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionImpl.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionKeyImpl.java66
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionManagerImpl.java382
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/EvictionEventImpl.java37
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/branch/BranchDispatcher.java190
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/branch/BranchRevisionCache.java500
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/lru/LRURevisionCache.java70
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/lru/RevisionHolder.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/mem/MEMRevisionCache.java156
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/noop/NOOPRevisionCache.java35
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/two/TwoLevelRevisionCache.java93
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java77
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/branch/CDOBranchUtil.java54
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/branch/InternalCDOBranch.java39
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/branch/InternalCDOBranchManager.java160
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/AbstractCDORevision.java707
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java712
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java302
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevisionManager.java172
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DetachedCDORevision.java48
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java11
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevisionDelta.java13
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevisionManager.java41
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/PointerCDORevision.java71
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/RevisionInfo.java539
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java258
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/SyntheticCDORevision.java51
64 files changed, 5277 insertions, 1230 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.common/META-INF/MANIFEST.MF
index f1332ab0fa..eec3a4b403 100644
--- a/plugins/org.eclipse.emf.cdo.common/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.cdo.common/META-INF/MANIFEST.MF
@@ -34,7 +34,17 @@ Export-Package: org.eclipse.emf.cdo.common;version="3.0.0",
org.eclipse.emf.cdo.server.net4j,
org.eclipse.emf.cdo.ui,
org.eclipse.emf.cdo.tests",
+ org.eclipse.emf.cdo.internal.common.branch;version="3.0.0";x-friends:="org.eclipse.emf.cdo.tests",
org.eclipse.emf.cdo.internal.common.bundle;version="3.0.0";x-internal:=true,
+ org.eclipse.emf.cdo.internal.common.commit;version="3.0.0";
+ x-friends:="org.eclipse.emf.cdo.common,
+ org.eclipse.emf.cdo.common.db,
+ org.eclipse.emf.cdo,
+ org.eclipse.emf.cdo.net4j,
+ org.eclipse.emf.cdo.server,
+ org.eclipse.emf.cdo.server.net4j,
+ org.eclipse.emf.cdo.ui,
+ org.eclipse.emf.cdo.tests",
org.eclipse.emf.cdo.internal.common.id;version="3.0.0";
x-friends:="org.eclipse.emf.cdo.common,
org.eclipse.emf.cdo.common.db,
@@ -81,6 +91,15 @@ Export-Package: org.eclipse.emf.cdo.common;version="3.0.0",
org.eclipse.emf.cdo.server.net4j,
org.eclipse.emf.cdo.ui,
org.eclipse.emf.cdo.tests",
+ org.eclipse.emf.cdo.internal.common.revision.cache.branch;version="3.0.0";
+ x-friends:="org.eclipse.emf.cdo.common,
+ org.eclipse.emf.cdo.common.db,
+ org.eclipse.emf.cdo,
+ org.eclipse.emf.cdo.net4j,
+ org.eclipse.emf.cdo.server,
+ org.eclipse.emf.cdo.server.net4j,
+ org.eclipse.emf.cdo.ui,
+ org.eclipse.emf.cdo.tests",
org.eclipse.emf.cdo.internal.common.revision.cache.lru;version="3.0.0";
x-friends:="org.eclipse.emf.cdo.common,
org.eclipse.emf.cdo.common.db,
@@ -127,6 +146,7 @@ Export-Package: org.eclipse.emf.cdo.common;version="3.0.0",
org.eclipse.emf.cdo.ui,
org.eclipse.emf.cdo.tests",
org.eclipse.emf.cdo.spi.common;version="3.0.0",
+ org.eclipse.emf.cdo.spi.common.branch;version="3.0.0",
org.eclipse.emf.cdo.spi.common.id;version="3.0.0",
org.eclipse.emf.cdo.spi.common.model;version="3.0.0",
org.eclipse.emf.cdo.spi.common.revision;version="3.0.0"
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonView.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonView.java
index 02a9028f2f..2e1c8e7cb6 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonView.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOCommonView.java
@@ -4,13 +4,13 @@
* 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.common;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.net4j.util.collection.Closeable;
@@ -18,23 +18,14 @@ import org.eclipse.net4j.util.collection.Closeable;
* @author Eike Stepper
* @since 2.0
*/
-public interface CDOCommonView extends Closeable
+public interface CDOCommonView extends CDOBranchPoint, Closeable
{
- public static final long UNSPECIFIED_DATE = CDORevision.UNSPECIFIED_DATE;
-
public int getViewID();
- public Type getViewType();
-
- public CDOCommonSession getSession();
-
- public long getTimeStamp();
-
/**
- * @author Eike Stepper
+ * @since 3.0
*/
- public enum Type
- {
- TRANSACTION, READONLY, AUDIT
- }
+ public boolean isReadOnly();
+
+ public CDOCommonSession getSession();
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOTimeProvider.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOTimeProvider.java
new file mode 100644
index 0000000000..206b31c165
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOTimeProvider.java
@@ -0,0 +1,20 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.common;
+
+/**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+public interface CDOTimeProvider
+{
+ public long getTimeStamp();
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranch.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranch.java
index eb1eb8808c..cbb5aeae7e 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranch.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranch.java
@@ -14,11 +14,35 @@ package org.eclipse.emf.cdo.common.branch;
* @author Eike Stepper
* @since 3.0
*/
-public interface CDOBranch
+public interface CDOBranch extends Comparable<CDOBranch>
{
+ public static final int MAIN_BRANCH_ID = 0;
+
+ public static final String MAIN_BRANCH_NAME = "MAIN";
+
+ public static final String PATH_SEPARATOR = "/";
+
+ public boolean isMainBranch();
+
public int getID();
public String getName();
- public CDOBranchTag getBase();
+ public CDOBranchPoint getBase();
+
+ public CDOBranchPoint getHead();
+
+ public CDOBranchPoint getPoint(long timeStamp);
+
+ public CDOBranchVersion getVersion(int version);
+
+ public CDOBranchManager getBranchManager();
+
+ public CDOBranch[] getBranches();
+
+ public CDOBranch getBranch(String path);
+
+ public CDOBranch createBranch(String name, long timeStamp);
+
+ public CDOBranch createBranch(String name);
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchCreatedEvent.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchCreatedEvent.java
new file mode 100644
index 0000000000..a3ce7d4414
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchCreatedEvent.java
@@ -0,0 +1,24 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.common.branch;
+
+import org.eclipse.net4j.util.event.IEvent;
+
+/**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+public interface CDOBranchCreatedEvent extends IEvent
+{
+ public CDOBranchManager getSource();
+
+ public CDOBranch getBranch();
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchManager.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchManager.java
new file mode 100644
index 0000000000..c4068048af
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchManager.java
@@ -0,0 +1,26 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.common.branch;
+
+import org.eclipse.net4j.util.event.INotifier;
+
+/**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+public interface CDOBranchManager extends INotifier
+{
+ public CDOBranch getMainBranch();
+
+ public CDOBranch getBranch(int branchID);
+
+ public CDOBranch getBranch(String path);
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchPoint.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchPoint.java
index 0e70230699..91751bf5c1 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchPoint.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchPoint.java
@@ -10,14 +10,15 @@
*/
package org.eclipse.emf.cdo.common.branch;
-
/**
* @author Eike Stepper
* @since 3.0
*/
-public interface CDOBranchPoint
+public interface CDOBranchPoint extends Comparable<CDOBranchPoint>
{
- public int getBranchID();
+ public static final long UNSPECIFIED_DATE = 0;
+
+ public CDOBranch getBranch();
public long getTimeStamp();
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchTag.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchTag.java
index fe9ec5d7ea..6311666ca3 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchTag.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchTag.java
@@ -10,7 +10,6 @@
*/
package org.eclipse.emf.cdo.common.branch;
-
/**
* @author Eike Stepper
* @since 3.0
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchVersion.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchVersion.java
new file mode 100644
index 0000000000..93188e7935
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/branch/CDOBranchVersion.java
@@ -0,0 +1,26 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.common.branch;
+
+/**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+public interface CDOBranchVersion
+{
+ public static final int UNSPECIFIED_VERSION = 0;
+
+ public static final int FIRST_VERSION = 1;
+
+ public CDOBranch getBranch();
+
+ public int getVersion();
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/commit/CDOCommit.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/commit/CDOCommit.java
index 26c7695ff7..772da37ae6 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/commit/CDOCommit.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/commit/CDOCommit.java
@@ -12,8 +12,6 @@ package org.eclipse.emf.cdo.common.commit;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
-import java.util.List;
-
/**
* @author Eike Stepper
* @since 3.0
@@ -22,7 +20,7 @@ public interface CDOCommit extends CDOBranchPoint
{
public String getUserID();
- public List<String> getComments();
+ public String getComment();
// public Set<CDOID> getNewResources();
//
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDAndBranch.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDAndBranch.java
new file mode 100644
index 0000000000..a304991f75
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDAndBranch.java
@@ -0,0 +1,25 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.common.id;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+
+/**
+ * @author Eike Stepper
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @since 3.0
+ */
+public interface CDOIDAndBranch
+{
+ public CDOID getID();
+
+ public CDOBranch getBranch();
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDAndVersion.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDAndVersion.java
index 90ae24eba3..3297607236 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDAndVersion.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDAndVersion.java
@@ -4,7 +4,7 @@
* 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
*/
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDAndVersionAndBranch.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDAndVersionAndBranch.java
new file mode 100644
index 0000000000..3959c96211
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDAndVersionAndBranch.java
@@ -0,0 +1,21 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.common.id;
+
+
+/**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+public interface CDOIDAndVersionAndBranch extends CDOIDAndVersion
+{
+ public int getBranchID();
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDUtil.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDUtil.java
index 0548603299..82ac77409e 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDUtil.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDUtil.java
@@ -13,9 +13,12 @@
*/
package org.eclipse.emf.cdo.common.id;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.id.CDOID.Type;
import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
import org.eclipse.emf.cdo.internal.common.bundle.OM;
+import org.eclipse.emf.cdo.internal.common.id.CDOIDAndBranchImpl;
+import org.eclipse.emf.cdo.internal.common.id.CDOIDAndVersionAndBranchImpl;
import org.eclipse.emf.cdo.internal.common.id.CDOIDAndVersionImpl;
import org.eclipse.emf.cdo.internal.common.id.CDOIDExternalImpl;
import org.eclipse.emf.cdo.internal.common.id.CDOIDMetaImpl;
@@ -351,6 +354,22 @@ public final class CDOIDUtil
}
/**
+ * @since 3.0
+ */
+ public static CDOIDAndBranch createIDAndBranch(CDOID id, CDOBranch branch)
+ {
+ return new CDOIDAndBranchImpl(id, branch);
+ }
+
+ /**
+ * @since 3.0
+ */
+ public static CDOIDAndVersionAndBranch createIDAndVersionAndBranch(CDOID id, int version, int branchID)
+ {
+ return new CDOIDAndVersionAndBranchImpl(id, version, branchID);
+ }
+
+ /**
* @since 2.0
*/
public static boolean equals(CDOID id1, CDOID id2)
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/io/CDODataInput.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/io/CDODataInput.java
index 9d44dfc0e7..d746ab8195 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/io/CDODataInput.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/io/CDODataInput.java
@@ -11,8 +11,13 @@
*/
package org.eclipse.emf.cdo.common.io;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDAndBranch;
import org.eclipse.emf.cdo.common.id.CDOIDAndVersion;
+import org.eclipse.emf.cdo.common.id.CDOIDAndVersionAndBranch;
import org.eclipse.emf.cdo.common.id.CDOIDMetaRange;
import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
import org.eclipse.emf.cdo.common.model.CDOPackageInfo;
@@ -59,10 +64,37 @@ public interface CDODataInput extends ExtendedDataInput
// /////////////////////////////////////////////////////////////////////////////////////////////////
+ /**
+ * @since 3.0
+ */
+ public CDOBranch readCDOBranch() throws IOException;
+
+ /**
+ * @since 3.0
+ */
+ public CDOBranchPoint readCDOBranchPoint() throws IOException;
+
+ /**
+ * @since 3.0
+ */
+ public CDOBranchVersion readCDOBranchVersion() throws IOException;
+
+ // /////////////////////////////////////////////////////////////////////////////////////////////////
+
public CDOID readCDOID() throws IOException;
public CDOIDAndVersion readCDOIDAndVersion() throws IOException;
+ /**
+ * @since 3.0
+ */
+ public CDOIDAndBranch readCDOIDAndBranch() throws IOException;
+
+ /**
+ * @since 3.0
+ */
+ public CDOIDAndVersionAndBranch readCDOIDAndVersionAndBranch() throws IOException;
+
public CDOIDMetaRange readCDOIDMetaRange() throws IOException;
// /////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/io/CDODataOutput.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/io/CDODataOutput.java
index aa391edec4..fa7fca9c35 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/io/CDODataOutput.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/io/CDODataOutput.java
@@ -11,8 +11,13 @@
*/
package org.eclipse.emf.cdo.common.io;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDAndBranch;
import org.eclipse.emf.cdo.common.id.CDOIDAndVersion;
+import org.eclipse.emf.cdo.common.id.CDOIDAndVersionAndBranch;
import org.eclipse.emf.cdo.common.id.CDOIDMetaRange;
import org.eclipse.emf.cdo.common.id.CDOIDProvider;
import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
@@ -67,10 +72,37 @@ public interface CDODataOutput extends ExtendedDataOutput
// /////////////////////////////////////////////////////////////////////////////////////////////////
+ /**
+ * @since 3.0
+ */
+ public void writeCDOBranch(CDOBranch branch) throws IOException;
+
+ /**
+ * @since 3.0
+ */
+ public void writeCDOBranchPoint(CDOBranchPoint branchPoint) throws IOException;
+
+ /**
+ * @since 3.0
+ */
+ public void writeCDOBranchVersion(CDOBranchVersion branchVersion) throws IOException;
+
+ // /////////////////////////////////////////////////////////////////////////////////////////////////
+
public void writeCDOID(CDOID id) throws IOException;
public void writeCDOIDAndVersion(CDOIDAndVersion idAndVersion) throws IOException;
+ /**
+ * @since 3.0
+ */
+ public void writeCDOIDAndBranch(CDOIDAndBranch idAndBranch) throws IOException;
+
+ /**
+ * @since 3.0
+ */
+ public void writeCDOIDAndVersionAndBranch(CDOIDAndVersionAndBranch idAndVersionAndBranch) throws IOException;
+
public void writeCDOIDMetaRange(CDOIDMetaRange metaRange) throws IOException;
// /////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java
index 1935038576..b2eb4dc15f 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java
@@ -29,67 +29,97 @@ public interface CDOProtocolConstants
public static final short SIGNAL_AUTHENTICATION = 2;
- public static final short SIGNAL_VIEWS_CHANGED = 4;
+ /**
+ * @since 3.0
+ */
+ public static final short SIGNAL_OPEN_VIEW = 3;
+
+ /**
+ * @since 3.0
+ */
+ public static final short SIGNAL_CHANGE_VIEW = 4;
+
+ /**
+ * @since 3.0
+ */
+ public static final short SIGNAL_CLOSE_VIEW = 5;
public static final short SIGNAL_LOAD_PACKAGES = 6;
- public static final short SIGNAL_LOAD_REVISION = 7;
+ /**
+ * @since 3.0
+ */
+ public static final short SIGNAL_LOAD_REVISIONS = 7;
+
+ public static final short SIGNAL_LOAD_REVISION_BY_VERSION = 8;
- public static final short SIGNAL_LOAD_REVISION_BY_TIME = 8;
+ public static final short SIGNAL_LOAD_CHUNK = 9;
- public static final short SIGNAL_LOAD_REVISION_BY_VERSION = 9;
+ public static final short SIGNAL_COMMIT_TRANSACTION = 10;
- public static final short SIGNAL_LOAD_CHUNK = 10;
+ public static final short SIGNAL_COMMIT_TRANSACTION_PHASE1 = 11;
- public static final short SIGNAL_VERIFY_REVISION = 11;
+ public static final short SIGNAL_COMMIT_TRANSACTION_PHASE2 = 12;
- public static final short SIGNAL_COMMIT_TRANSACTION = 12;
+ public static final short SIGNAL_COMMIT_TRANSACTION_PHASE3 = 13;
- public static final short SIGNAL_COMMIT_TRANSACTION_PHASE1 = 13;
+ public static final short SIGNAL_COMMIT_TRANSACTION_CANCEL = 14;
- public static final short SIGNAL_COMMIT_TRANSACTION_PHASE2 = 14;
+ public static final short SIGNAL_COMMIT_NOTIFICATION = 15;
- public static final short SIGNAL_COMMIT_TRANSACTION_PHASE3 = 15;
+ public static final short SIGNAL_QUERY = 16;
- public static final short SIGNAL_COMMIT_TRANSACTION_CANCEL = 16;
+ public static final short SIGNAL_QUERY_CANCEL = 17;
- public static final short SIGNAL_COMMIT_NOTIFICATION = 17;
+ public static final short SIGNAL_SYNC_REVISIONS = 18;
- public static final short SIGNAL_QUERY = 18;
+ public static final short SIGNAL_PASSIVE_UPDATE = 19;
- public static final short SIGNAL_QUERY_CANCEL = 19;
+ public static final short SIGNAL_CHANGE_SUBSCRIPTION = 20;
- public static final short SIGNAL_SYNC_REVISIONS = 20;
+ public static final short SIGNAL_REPOSITORY_TIME = 21;
- public static final short SIGNAL_PASSIVE_UPDATE = 21;
+ public static final short SIGNAL_LOCK_OBJECTS = 22;
- public static final short SIGNAL_CHANGE_SUBSCRIPTION = 22;
+ public static final short SIGNAL_UNLOCK_OBJECTS = 23;
- public static final short SIGNAL_SET_AUDIT = 23;
+ public static final short SIGNAL_OBJECT_LOCKED = 24;
- public static final short SIGNAL_REPOSITORY_TIME = 24;
+ public static final short SIGNAL_GET_REMOTE_SESSIONS = 25;
- public static final short SIGNAL_LOCK_OBJECTS = 25;
+ /**
+ * @since 3.0
+ */
+ public static final short SIGNAL_REMOTE_MESSAGE = 26;
- public static final short SIGNAL_UNLOCK_OBJECTS = 26;
+ /**
+ * @since 3.0
+ */
+ public static final short SIGNAL_REMOTE_MESSAGE_NOTIFICATION = 27;
- public static final short SIGNAL_OBJECT_LOCKED = 27;
+ public static final short SIGNAL_UNSUBSCRIBE_REMOTE_SESSIONS = 28;
- public static final short SIGNAL_GET_REMOTE_SESSIONS = 28;
+ public static final short SIGNAL_REMOTE_SESSION_NOTIFICATION = 29;
/**
* @since 3.0
*/
- public static final short SIGNAL_REMOTE_MESSAGE = 29;
+ public static final short SIGNAL_CREATE_BRANCH = 30;
/**
* @since 3.0
*/
- public static final short SIGNAL_REMOTE_MESSAGE_NOTIFICATION = 30;
+ public static final short SIGNAL_LOAD_BRANCH = 31;
- public static final short SIGNAL_UNSUBSCRIBE_REMOTE_SESSIONS = 31;
+ /**
+ * @since 3.0
+ */
+ public static final short SIGNAL_LOAD_SUB_BRANCHES = 32;
- public static final short SIGNAL_REMOTE_SESSION_NOTIFICATION = 32;
+ /**
+ * @since 3.0
+ */
+ public static final short SIGNAL_BRANCH_NOTIFICATION = 33;
// //////////////////////////////////////////////////////////////////////
// Session Management
@@ -99,11 +129,6 @@ public interface CDOProtocolConstants
public static final int ERROR_NO_SESSION = -2;
// //////////////////////////////////////////////////////////////////////
- // View Management
-
- public static final byte VIEW_CLOSED = -1;
-
- // //////////////////////////////////////////////////////////////////////
// Query Support
public static final String QUERY_LANGUAGE_RESOURCES = "resources"; //$NON-NLS-1$
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevision.java
index 24e6930b08..aa4d816445 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevision.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevision.java
@@ -11,7 +11,8 @@
*/
package org.eclipse.emf.cdo.common.revision;
-import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.ecore.EClass;
@@ -19,14 +20,17 @@ import org.eclipse.emf.ecore.EClass;
/**
* @author Eike Stepper
*/
-public interface CDORevision
+public interface CDORevision extends CDORevisionKey, CDOBranchPoint
{
- public static final long UNSPECIFIED_DATE = 0;
+ /**
+ * @since 3.0
+ */
+ public static final int MAIN_BRANCH_ID = CDOBranch.MAIN_BRANCH_ID;
/**
- * @since 2.0
+ * @since 3.0
*/
- public static final int UNSPECIFIED_VERSION = 0;
+ public static final int FIRST_VERSION = 1;
public static final int UNCHUNKED = -1;
@@ -45,25 +49,20 @@ public interface CDORevision
*/
public EClass getEClass();
- public CDOID getID();
-
- // /**
- // * @since 3.0
- // */
- // public int getBranchID();
-
public int getVersion();
- public long getCreated();
-
public long getRevised();
- public boolean isCurrent();
+ /**
+ * Returns <code>true</code> exactly if {@link #getTimeStamp()} does not return {@link #UNSPECIFIED_DATE},
+ * <code>false</code> otherwise.
+ *
+ * @since 3.0
+ */
+ public boolean isHistorical();
public boolean isValid(long timeStamp);
- public boolean isTransactional();
-
/**
* @since 2.0
*/
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionKey.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionKey.java
new file mode 100644
index 0000000000..7d1de6474c
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionKey.java
@@ -0,0 +1,23 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.common.revision;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.common.id.CDOID;
+
+/**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+public interface CDORevisionKey extends CDOBranchVersion
+{
+ public CDOID getID();
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionManager.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionManager.java
index ca83e0c0a9..0ddc4a67ef 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionManager.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionManager.java
@@ -10,11 +10,12 @@
*/
package org.eclipse.emf.cdo.common.revision;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.ecore.EClass;
-import java.util.Collection;
import java.util.List;
/**
@@ -28,28 +29,16 @@ public interface CDORevisionManager
*/
public EClass getObjectType(CDOID id);
- public boolean containsRevision(CDOID id);
+ public boolean containsRevision(CDOID id, CDOBranchPoint branchPoint);
- public boolean containsRevisionByTime(CDOID id, long timeStamp);
-
- public boolean containsRevisionByVersion(CDOID id, int version);
-
- public CDORevision getRevision(CDOID id, int referenceChunk, int prefetchDepth);
-
- public CDORevision getRevision(CDOID id, int referenceChunk, int prefetchDepth, boolean loadOnDemand);
-
- public CDORevision getRevisionByTime(CDOID id, int referenceChunk, int prefetchDepth, long timeStamp);
-
- public CDORevision getRevisionByTime(CDOID id, int referenceChunk, int prefetchDepth, long timeStamp,
+ public CDORevision getRevision(CDOID id, CDOBranchPoint branchPoint, int referenceChunk, int prefetchDepth,
boolean loadOnDemand);
- public CDORevision getRevisionByVersion(CDOID id, int referenceChunk, int prefetchDepth, int version);
-
- public CDORevision getRevisionByVersion(CDOID id, int referenceChunk, int prefetchDepth, int version,
- boolean loadOnDemand);
+ public List<CDORevision> getRevisions(List<CDOID> ids, CDOBranchPoint branchPoint, int referenceChunk,
+ int prefetchDepth, boolean loadOnDemand);
- public List<CDORevision> getRevisions(Collection<CDOID> ids, int referenceChunk, int prefetchDepth);
+ public boolean containsRevisionByVersion(CDOID id, CDOBranchVersion branchVersion);
- public List<CDORevision> getRevisionsByTime(Collection<CDOID> ids, int referenceChunk, int prefetchDepth,
- long timeStamp, boolean loadOnDemand);
+ public CDORevision getRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int referenceChunk,
+ boolean loadOnDemand);
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java
index fdb12488f8..39ed880b3a 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java
@@ -10,16 +10,24 @@
*/
package org.eclipse.emf.cdo.common.revision;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDTemp;
import org.eclipse.emf.cdo.internal.common.messages.Messages;
import org.eclipse.emf.cdo.internal.common.revision.CDOFeatureMapEntryImpl;
import org.eclipse.emf.cdo.internal.common.revision.CDORevisionImpl;
+import org.eclipse.emf.cdo.internal.common.revision.CDORevisionKeyImpl;
import org.eclipse.emf.cdo.spi.common.revision.CDOFeatureMapEntry;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.FeatureMap;
+import java.io.PrintStream;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
import java.util.Map;
/**
@@ -34,6 +42,22 @@ public final class CDORevisionUtil
}
/**
+ * @since 3.0
+ */
+ public static CDORevisionKey createRevisionKey(CDOID id, CDOBranch branch, int version)
+ {
+ return new CDORevisionKeyImpl(id, branch, version);
+ }
+
+ /**
+ * @since 3.0
+ */
+ public static CDORevisionKey createRevisionKey(CDORevisionKey source)
+ {
+ return new CDORevisionKeyImpl(source.getID(), source.getBranch(), source.getVersion());
+ }
+
+ /**
* @since 2.0
*/
public static FeatureMap.Entry createFeatureMapEntry(EStructuralFeature feature, Object value)
@@ -57,15 +81,59 @@ public final class CDORevisionUtil
/**
* @since 3.0
*/
- public static int getOriginalVersion(CDORevision revision)
+ public static void dumpAllRevisions(Map<CDOBranch, List<CDORevision>> map, PrintStream out)
{
- int version = revision.getVersion();
- if (revision.isTransactional())
+ final int pad = 48;
+ ArrayList<CDOBranch> branches = new ArrayList<CDOBranch>(map.keySet());
+ Collections.sort(branches);
+
+ for (CDOBranch branch : branches)
+ {
+ out.println(padTimeRange(branch.getName() + "[" + branch.getID() + "]", pad, branch.getBase().getTimeStamp(),
+ CDORevision.UNSPECIFIED_DATE));
+
+ List<CDORevision> revisions = map.get(branch);
+ Collections.sort(revisions, new Comparator<CDORevision>()
+ {
+ public int compare(CDORevision rev1, CDORevision rev2)
+ {
+ int result = rev1.getID().compareTo(rev2.getID());
+ if (result == 0)
+ {
+ int version1 = rev1.getVersion();
+ int version2 = rev2.getVersion();
+ result = version1 < version2 ? -1 : version1 == version2 ? 0 : 1;
+ }
+
+ return result;
+ }
+ });
+
+ for (CDORevision revision : revisions)
+ {
+ out.println(padTimeRange(" " + revision, pad, revision.getTimeStamp(), revision.getRevised()));
+ }
+
+ out.println();
+ }
+ }
+
+ private static String padTimeRange(String s, int pos, long t1, long t2)
+ {
+ StringBuffer buffer = new StringBuffer(s);
+ while (buffer.length() < pos)
+ {
+ buffer.append(' ');
+ }
+
+ String revised = "*";
+ if (t2 != CDORevision.UNSPECIFIED_DATE)
{
- --version;
+ revised = MessageFormat.format("{0,date} {0,time,HH:mm:ss:SSS}", t2);
}
- return version;
+ buffer.append(MessageFormat.format("{0,date} {0,time,HH:mm:ss:SSS}/{1}", t1, revised));
+ return buffer.toString();
}
/**
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/cache/CDORevisionCache.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/cache/CDORevisionCache.java
index e19f77ebc0..cf81bf809c 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/cache/CDORevisionCache.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/cache/CDORevisionCache.java
@@ -10,8 +10,12 @@
*/
package org.eclipse.emf.cdo.common.revision.cache;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
+import org.eclipse.emf.cdo.internal.common.revision.cache.mem.MEMRevisionCache;
import org.eclipse.emf.cdo.internal.common.revision.cache.noop.NOOPRevisionCache;
import org.eclipse.net4j.util.event.IEvent;
@@ -25,62 +29,50 @@ import java.util.List;
* @author Eike Stepper
* @since 2.0
*/
-public interface CDORevisionCache extends INotifier, CDORevisionCacheAdder
+public interface CDORevisionCache extends INotifier
{
/**
* @since 3.0
*/
public static final CDORevisionCache NOOP = NOOPRevisionCache.INSTANCE;
- public EClass getObjectType(CDOID id);
-
/**
* @since 3.0
*/
- public CDORevision getRevision(CDOID id);
+ public boolean isSupportingBranches();
- /**
- * @since 3.0
- */
- public CDORevision getRevisionByTime(CDOID id, long timeStamp);
-
- /**
- * @since 3.0
- */
- public CDORevision getRevisionByVersion(CDOID id, int version);
+ public EClass getObjectType(CDOID id);
/**
* @since 3.0
*/
- public void removeRevision(CDORevision revision);
+ public CDORevision getRevision(CDOID id, CDOBranchPoint branchPoint);
/**
* @since 3.0
*/
- public CDORevision removeRevision(CDOID id, int version);
+ public CDORevision getRevisionByVersion(CDOID id, CDOBranchVersion branchVersion);
/**
* Returns a list of {@link CDORevision revisions} that are current.
+ *
+ * @since 3.0
*/
- public List<CDORevision> getRevisions();
-
- public void clear();
+ public List<CDORevision> getCurrentRevisions();
/**
* @author Eike Stepper
*/
- public interface EvictionEvent extends IEvent
+ public interface EvictionEvent extends IEvent, CDORevisionKey
{
/**
* @since 3.0
*/
public CDORevisionCache getSource();
- public CDOID getID();
-
- public int getVersion();
-
/**
+ * May be <code>null</code> for certain cache implementations, e.g. {@link MEMRevisionCache}.
+ *
* @since 3.0
*/
public CDORevision getRevision();
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/cache/CDORevisionCacheFactory.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/cache/CDORevisionCacheFactory.java
new file mode 100644
index 0000000000..a42f133f60
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/cache/CDORevisionCacheFactory.java
@@ -0,0 +1,51 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.common.revision.cache;
+
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+
+/**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+public interface CDORevisionCacheFactory
+{
+ public CDORevisionCache createRevisionCache(CDORevision revision);
+
+ /**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+ public static class PrototypeInstantiator implements CDORevisionCacheFactory
+ {
+ private CDORevisionCache prototype;
+
+ public PrototypeInstantiator(CDORevisionCache prototype)
+ {
+ this.prototype = prototype;
+ }
+
+ public CDORevisionCache getPrototype()
+ {
+ return prototype;
+ }
+
+ public CDORevisionCache createRevisionCache(CDORevision revision)
+ {
+ if (revision.getBranch().isMainBranch())
+ {
+ return prototype;
+ }
+
+ return ((InternalCDORevisionCache)prototype).instantiate(revision);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/cache/CDORevisionCacheUtil.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/cache/CDORevisionCacheUtil.java
index 1df3b1202e..a5b3011d5e 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/cache/CDORevisionCacheUtil.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/cache/CDORevisionCacheUtil.java
@@ -4,12 +4,14 @@
* 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.common.revision.cache;
+import org.eclipse.emf.cdo.internal.common.revision.cache.branch.BranchDispatcher;
+import org.eclipse.emf.cdo.internal.common.revision.cache.branch.BranchRevisionCache;
import org.eclipse.emf.cdo.internal.common.revision.cache.lru.LRURevisionCache;
import org.eclipse.emf.cdo.internal.common.revision.cache.mem.MEMRevisionCache;
import org.eclipse.emf.cdo.internal.common.revision.cache.two.TwoLevelRevisionCache;
@@ -54,8 +56,42 @@ public final class CDORevisionCacheUtil
public static CDORevisionCache createTwoLevelCache(CDORevisionCache level1, CDORevisionCache level2)
{
TwoLevelRevisionCache cache = new TwoLevelRevisionCache();
- cache.setLevel1(level1);
- cache.setLevel2(level2);
+ cache.setLevel1((InternalCDORevisionCache)level1);
+ cache.setLevel2((InternalCDORevisionCache)level2);
+ return cache;
+ }
+
+ /**
+ * Creates and returns a new memory sensitive revision cache that supports branches.
+ *
+ * @since 3.0
+ */
+ public static CDORevisionCache createBranchRevisionCache()
+ {
+ return new BranchRevisionCache();
+ }
+
+ /**
+ * Creates and returns a new branch dispatcher cache.
+ *
+ * @since 3.0
+ */
+ public static CDORevisionCache createBranchDispatcher(CDORevisionCacheFactory factory)
+ {
+ BranchDispatcher cache = new BranchDispatcher();
+ cache.setFactory(factory);
+ return cache;
+ }
+
+ /**
+ * Creates and returns a new branch dispatcher cache.
+ *
+ * @since 3.0
+ */
+ public static CDORevisionCache createBranchDispatcher(CDORevisionCache protoType)
+ {
+ BranchDispatcher cache = new BranchDispatcher();
+ cache.setFactory(new CDORevisionCacheFactory.PrototypeInstantiator(protoType));
return cache;
}
@@ -69,12 +105,19 @@ public final class CDORevisionCacheUtil
}
/**
- * Identical to calling
- * <p>
- * <code>{@link #createDefaultCache(int, int) createDefaultCache}({@link #DEFAULT_CAPACITY_CURRENT}, {@link #DEFAULT_CAPACITY_REVISED})</code>
+ * Identical to calling {@link #createBranchRevisionCache() createBranchRevisionCache()} if
+ * <code>supportingBranches</code> is <code>true</code>, {@link #createDefaultCache(int, int)
+ * createDefaultCache(DEFAULT_CAPACITY_CURRENT, DEFAULT_CAPACITY_REVISED)} otherwise.
+ *
+ * @since 3.0
*/
- public static CDORevisionCache createDefaultCache()
+ public static CDORevisionCache createDefaultCache(boolean supportingBranches)
{
- return createDefaultCache(DEFAULT_CAPACITY_CURRENT, DEFAULT_CAPACITY_REVISED);
+ // if (supportingBranches)
+ {
+ return createBranchRevisionCache();
+ }
+
+ // return createDefaultCache(DEFAULT_CAPACITY_CURRENT, DEFAULT_CAPACITY_REVISED);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/cache/InternalCDORevisionCache.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/cache/InternalCDORevisionCache.java
new file mode 100644
index 0000000000..4ce55acf25
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/cache/InternalCDORevisionCache.java
@@ -0,0 +1,38 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.common.revision.cache;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+
+import org.eclipse.net4j.util.lifecycle.ILifecycle;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+public interface InternalCDORevisionCache extends CDORevisionCache, ILifecycle
+{
+ public InternalCDORevisionCache instantiate(CDORevision revision);
+
+ public boolean addRevision(CDORevision revision);
+
+ public CDORevision removeRevision(CDOID id, CDOBranchVersion branchVersion);
+
+ public void clear();
+
+ public Map<CDOBranch, List<CDORevision>> getAllRevisions();
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/delta/CDORevisionDelta.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/delta/CDORevisionDelta.java
index 2615adfbb1..0952086524 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/delta/CDORevisionDelta.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/delta/CDORevisionDelta.java
@@ -11,8 +11,8 @@
*/
package org.eclipse.emf.cdo.common.revision.delta;
-import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
import org.eclipse.emf.ecore.EClass;
@@ -22,25 +22,13 @@ import java.util.List;
* @author Eike Stepper
* @noimplement This interface is not intended to be implemented by clients.
*/
-public interface CDORevisionDelta
+public interface CDORevisionDelta extends CDORevisionKey
{
- public CDOID getID();
-
/**
* @since 3.0
*/
public EClass getEClass();
- /**
- * Specify the version of the object BEFORE it was modified.
- */
- public int getOriginVersion();
-
- /**
- * Specify the version of the object AFTER it was modified.
- */
- public int getDirtyVersion();
-
public List<CDOFeatureDelta> getFeatureDeltas();
public void apply(CDORevision revision);
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/branch/CDOBranchImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/branch/CDOBranchImpl.java
new file mode 100644
index 0000000000..d2bf275576
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/branch/CDOBranchImpl.java
@@ -0,0 +1,276 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.internal.common.branch;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
+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.branch.InternalCDOBranchManager.BranchLoader.BranchInfo;
+import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager.BranchLoader.SubBranchInfo;
+
+import java.text.MessageFormat;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOBranchImpl implements InternalCDOBranch
+{
+ public static final int ILLEGAL_BRANCH_ID = Integer.MIN_VALUE;
+
+ private int id;
+
+ private String name;
+
+ private Object baseOrBranchManager;
+
+ private CDOBranchPoint head;
+
+ private InternalCDOBranch[] branches;
+
+ public CDOBranchImpl(int id, String name, CDOBranchPoint base)
+ {
+ this.id = id;
+ this.name = name;
+ baseOrBranchManager = base;
+ head = CDOBranchUtil.createBranchPoint(this, CDOBranchPoint.UNSPECIFIED_DATE);
+ }
+
+ public CDOBranchImpl(int id, InternalCDOBranchManager branchManager)
+ {
+ this.id = id;
+ baseOrBranchManager = branchManager;
+ }
+
+ public boolean isMainBranch()
+ {
+ return false;
+ }
+
+ public InternalCDOBranchManager getBranchManager()
+ {
+ if (isProxy())
+ {
+ return (InternalCDOBranchManager)baseOrBranchManager;
+ }
+
+ CDOBranchPoint base = (CDOBranchPoint)baseOrBranchManager;
+ return (InternalCDOBranchManager)base.getBranch().getBranchManager();
+ }
+
+ public int getID()
+ {
+ return id;
+ }
+
+ public String getName()
+ {
+ loadIfNeeded();
+ return name;
+ }
+
+ public boolean isProxy()
+ {
+ return name == null;
+ }
+
+ public CDOBranchPoint getBase()
+ {
+ loadIfNeeded();
+ return (CDOBranchPoint)baseOrBranchManager;
+ }
+
+ public CDOBranchPoint getHead()
+ {
+ return head;
+ }
+
+ public CDOBranchPoint getPoint(long timeStamp)
+ {
+ return CDOBranchUtil.createBranchPoint(this, timeStamp);
+ }
+
+ public CDOBranchVersion getVersion(int version)
+ {
+ return CDOBranchUtil.createBranchVersion(this, version);
+ }
+
+ public InternalCDOBranch createBranch(String name, long timeStamp)
+ {
+ return getBranchManager().createBranch(name, this, timeStamp);
+ }
+
+ public InternalCDOBranch createBranch(String name)
+ {
+ return getBranchManager().createBranch(name, this, CDOBranchPoint.UNSPECIFIED_DATE);
+ }
+
+ public synchronized InternalCDOBranch[] getBranches()
+ {
+ loadIfNeeded();
+ if (branches == null)
+ {
+ InternalCDOBranchManager branchManager = getBranchManager();
+ SubBranchInfo[] infos = branchManager.getBranchLoader().loadSubBranches(id);
+ branches = new InternalCDOBranch[infos.length];
+ for (int i = 0; i < infos.length; i++)
+ {
+ SubBranchInfo info = infos[i];
+ branches[i] = branchManager.getBranch(info.getID(), info.getName(), info.getBaseTimeStamp(), this);
+ }
+ }
+
+ return branches;
+ }
+
+ public InternalCDOBranch getBranch(String path)
+ {
+ while (path.endsWith(PATH_SEPARATOR))
+ {
+ path = path.substring(0, path.length() - PATH_SEPARATOR.length());
+ }
+
+ int sep = path.indexOf(PATH_SEPARATOR);
+ if (sep == -1)
+ {
+ return getChild(path);
+ }
+
+ String name = path.substring(0, sep);
+ InternalCDOBranch child = getChild(name);
+
+ // Recurse
+ String rest = path.substring(sep + 1);
+ return child.getBranch(rest);
+ }
+
+ private InternalCDOBranch getChild(String name)
+ {
+ InternalCDOBranch[] branches = getBranches();
+ for (InternalCDOBranch branch : branches)
+ {
+ if (name.equals(branch.getName()))
+ {
+ return branch;
+ }
+ }
+
+ return null;
+ }
+
+ public BranchInfo getBranchInfo()
+ {
+ CDOBranchPoint base = getBase();
+ return new BranchInfo(getName(), base.getBranch().getID(), base.getTimeStamp());
+ }
+
+ public void setBranchInfo(String name, InternalCDOBranch baseBranch, long baseTimeStamp)
+ {
+ this.name = name;
+ baseOrBranchManager = CDOBranchUtil.createBranchPoint(baseBranch, baseTimeStamp);
+ }
+
+ public synchronized void addChild(InternalCDOBranch branch)
+ {
+ if (branches == null)
+ {
+ branches = new InternalCDOBranch[] { branch };
+ }
+ else
+ {
+ InternalCDOBranch[] newBranches = new InternalCDOBranch[branches.length + 1];
+ System.arraycopy(branches, 0, newBranches, 0, branches.length);
+ newBranches[branches.length] = branch;
+ branches = newBranches;
+ }
+ }
+
+ public int compareTo(CDOBranch o)
+ {
+ int otherID = o.getID();
+ return id < otherID ? -1 : id == otherID ? 0 : 1;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return id;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+
+ if (obj instanceof CDOBranch)
+ {
+ CDOBranch that = (CDOBranch)obj;
+ return id == that.getID();
+ }
+
+ return false;
+ }
+
+ @Override
+ public String toString()
+ {
+ if (isProxy())
+ {
+ return MessageFormat.format("Branch[id={0}, PROXY]", id);
+ }
+
+ return MessageFormat.format("Branch[id={0}, name={1}]", id, name);
+ }
+
+ private synchronized void loadIfNeeded()
+ {
+ if (isProxy())
+ {
+ InternalCDOBranchManager branchManager = (InternalCDOBranchManager)baseOrBranchManager;
+ BranchInfo branchInfo = branchManager.getBranchLoader().loadBranch(id);
+
+ CDOBranch baseBranch = branchManager.getBranch(branchInfo.getBaseBranchID());
+ name = branchInfo.getName();
+ baseOrBranchManager = CDOBranchUtil.createBranchPoint(baseBranch, branchInfo.getBaseTimeStamp());
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class Main extends CDOBranchImpl
+ {
+ private InternalCDOBranchManager branchManager;
+
+ public Main(InternalCDOBranchManager branchManager, long timeStamp)
+ {
+ super(MAIN_BRANCH_ID, MAIN_BRANCH_NAME, CDOBranchUtil.createBranchPoint(null, timeStamp));
+ this.branchManager = branchManager;
+ }
+
+ @Override
+ public boolean isMainBranch()
+ {
+ return true;
+ }
+
+ @Override
+ public InternalCDOBranchManager getBranchManager()
+ {
+ return branchManager;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/branch/CDOBranchManagerImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/branch/CDOBranchManagerImpl.java
new file mode 100644
index 0000000000..64ae67e932
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/branch/CDOBranchManagerImpl.java
@@ -0,0 +1,229 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.internal.common.branch;
+
+import org.eclipse.emf.cdo.common.CDOTimeProvider;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchCreatedEvent;
+import org.eclipse.emf.cdo.common.branch.CDOBranchManager;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
+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.branch.InternalCDOBranchManager.BranchLoader.BranchInfo;
+
+import org.eclipse.net4j.util.event.Event;
+import org.eclipse.net4j.util.lifecycle.Lifecycle;
+import org.eclipse.net4j.util.ref.ReferenceValueMap;
+import org.eclipse.net4j.util.ref.ReferenceValueMap.Soft;
+
+import java.util.Map;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOBranchManagerImpl extends Lifecycle implements InternalCDOBranchManager
+{
+ private BranchLoader branchLoader;
+
+ private CDOTimeProvider timeProvider;
+
+ private InternalCDOBranch mainBranch;
+
+ private Map<Integer, InternalCDOBranch> branches = createMap();
+
+ public CDOBranchManagerImpl()
+ {
+ }
+
+ public BranchLoader getBranchLoader()
+ {
+ return branchLoader;
+ }
+
+ public void setBranchLoader(BranchLoader branchLoader)
+ {
+ checkInactive();
+ this.branchLoader = branchLoader;
+ }
+
+ public CDOTimeProvider getTimeProvider()
+ {
+ return timeProvider;
+ }
+
+ public void setTimeProvider(CDOTimeProvider timeProvider)
+ {
+ this.timeProvider = timeProvider;
+ }
+
+ public void initMainBranch(long repositoryCreationTime)
+ {
+ checkInactive();
+ mainBranch = new CDOBranchImpl.Main(this, repositoryCreationTime);
+ }
+
+ public void handleBranchCreated(InternalCDOBranch branch)
+ {
+ CDOBranchPoint base = branch.getBase();
+ InternalCDOBranch baseBranch = (InternalCDOBranch)base.getBranch();
+ baseBranch.addChild(branch);
+
+ fireEvent(new BranchCreatedEvent(branch));
+ }
+
+ public InternalCDOBranch getMainBranch()
+ {
+ checkActive();
+ return mainBranch;
+ }
+
+ public InternalCDOBranch getBranch(int branchID)
+ {
+ checkActive();
+ if (branchID == CDOBranch.MAIN_BRANCH_ID)
+ {
+ return mainBranch;
+ }
+
+ InternalCDOBranch branch;
+ synchronized (branches)
+ {
+ branch = branches.get(branchID);
+ if (branch == null)
+ {
+ branch = new CDOBranchImpl(branchID, this);
+ putBranch(branch);
+ }
+ }
+
+ return branch;
+ }
+
+ public InternalCDOBranch getBranch(int id, String name, long baseTimeStamp, InternalCDOBranch base)
+ {
+ synchronized (branches)
+ {
+ InternalCDOBranch branch = branches.get(id);
+ if (branch == null)
+ {
+ branch = new CDOBranchImpl(id, name, CDOBranchUtil.createBranchPoint(base, baseTimeStamp));
+ putBranch(branch);
+ }
+ else if (branch.isProxy())
+ {
+ branch.setBranchInfo(name, base, baseTimeStamp);
+ }
+
+ return branch;
+ }
+ }
+
+ public InternalCDOBranch getBranch(String path)
+ {
+ int sep = path.indexOf(CDOBranch.PATH_SEPARATOR);
+ if (sep == -1)
+ {
+ if (CDOBranch.MAIN_BRANCH_NAME.equals(path))
+ {
+ return mainBranch;
+ }
+
+ return null;
+ }
+
+ String name = path.substring(0, sep);
+ if (CDOBranch.MAIN_BRANCH_NAME.equals(name))
+ {
+ String rest = path.substring(sep + 1);
+ return mainBranch.getBranch(rest);
+ }
+
+ return null;
+ }
+
+ public InternalCDOBranch createBranch(String name, InternalCDOBranch baseBranch, long baseTimeStamp)
+ {
+ checkActive();
+
+ if (baseTimeStamp == CDOBranchPoint.UNSPECIFIED_DATE)
+ {
+ baseTimeStamp = timeProvider.getTimeStamp();
+ }
+
+ int branchID = branchLoader.createBranch(new BranchInfo(name, baseBranch.getID(), baseTimeStamp));
+ CDOBranchPoint base = CDOBranchUtil.createBranchPoint(baseBranch, baseTimeStamp);
+ InternalCDOBranch branch = new CDOBranchImpl(branchID, name, base);
+ synchronized (branches)
+ {
+ putBranch(branch);
+ }
+
+ handleBranchCreated(branch);
+ return branch;
+ }
+
+ /**
+ * {@link #branches} must be synchronized by caller!
+ */
+ private boolean putBranch(InternalCDOBranch branch)
+ {
+ int id = branch.getID();
+ if (branches.containsKey(id))
+ {
+ return false;
+ }
+
+ branches.put(id, branch);
+ return true;
+ }
+
+ protected Soft<Integer, InternalCDOBranch> createMap()
+ {
+ return new ReferenceValueMap.Soft<Integer, InternalCDOBranch>();
+ }
+
+ @Override
+ protected void doBeforeActivate() throws Exception
+ {
+ super.doBeforeActivate();
+ checkNull(branchLoader, "branchLoader");
+ checkNull(timeProvider, "timeProvider");
+ checkNull(mainBranch, "mainBranch");
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private static final class BranchCreatedEvent extends Event implements CDOBranchCreatedEvent
+ {
+ private static final long serialVersionUID = 1L;
+
+ private CDOBranch branch;
+
+ public BranchCreatedEvent(CDOBranch branch)
+ {
+ super(branch.getBranchManager());
+ this.branch = branch;
+ }
+
+ @Override
+ public CDOBranchManager getSource()
+ {
+ return (CDOBranchManager)super.getSource();
+ }
+
+ public CDOBranch getBranch()
+ {
+ return branch;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/branch/CDOBranchPointImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/branch/CDOBranchPointImpl.java
new file mode 100644
index 0000000000..6de4e1df9f
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/branch/CDOBranchPointImpl.java
@@ -0,0 +1,83 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.internal.common.branch;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+
+import java.text.MessageFormat;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOBranchPointImpl implements CDOBranchPoint
+{
+ private CDOBranch branch;
+
+ private long timeStamp;
+
+ public CDOBranchPointImpl(CDOBranch branch, long timeStamp)
+ {
+ this.branch = branch;
+ this.timeStamp = timeStamp;
+ }
+
+ public CDOBranch getBranch()
+ {
+ return branch;
+ }
+
+ public long getTimeStamp()
+ {
+ return timeStamp;
+ }
+
+ public int compareTo(CDOBranchPoint o)
+ {
+ int result = branch.compareTo(o.getBranch());
+ if (result == 0)
+ {
+ long timeStamp2 = o.getTimeStamp();
+ result = timeStamp < timeStamp2 ? -1 : timeStamp == timeStamp2 ? 0 : 1;
+ }
+
+ return result;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return branch.hashCode() ^ new Long(timeStamp).hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+
+ if (obj instanceof CDOBranchPoint)
+ {
+ CDOBranchPoint that = (CDOBranchPoint)obj;
+ return branch.equals(that.getBranch()) && timeStamp == that.getTimeStamp();
+ }
+
+ return false;
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("BranchPoint[{0}, {1,date} {1,time,HH:mm:ss:SSS}]", branch, timeStamp);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/branch/CDOBranchVersionImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/branch/CDOBranchVersionImpl.java
new file mode 100644
index 0000000000..4482c2bb2c
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/branch/CDOBranchVersionImpl.java
@@ -0,0 +1,71 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.internal.common.branch;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+
+import java.text.MessageFormat;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOBranchVersionImpl implements CDOBranchVersion
+{
+ private CDOBranch branch;
+
+ private int version;
+
+ public CDOBranchVersionImpl(CDOBranch branch, int version)
+ {
+ this.branch = branch;
+ this.version = version;
+ }
+
+ public CDOBranch getBranch()
+ {
+ return branch;
+ }
+
+ public int getVersion()
+ {
+ return version;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return branch.hashCode() ^ version;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+
+ if (obj instanceof CDOBranchVersion)
+ {
+ CDOBranchVersion that = (CDOBranchVersion)obj;
+ return branch.equals(that.getBranch()) && version == that.getVersion();
+ }
+
+ return false;
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("BranchVersion[{0}, v{1}]", branch, version);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/commit/CDOCommitImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/commit/CDOCommitImpl.java
new file mode 100644
index 0000000000..89c1a7033e
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/commit/CDOCommitImpl.java
@@ -0,0 +1,42 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.internal.common.commit;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.commit.CDOCommit;
+import org.eclipse.emf.cdo.internal.common.branch.CDOBranchPointImpl;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOCommitImpl extends CDOBranchPointImpl implements CDOCommit
+{
+ private String userID;
+
+ private String comment;
+
+ public CDOCommitImpl(CDOBranch branch, long timeStamp, String userID, String comment)
+ {
+ super(branch, timeStamp);
+ this.userID = userID;
+ this.comment = comment;
+ }
+
+ public String getUserID()
+ {
+ return userID;
+ }
+
+ public String getComment()
+ {
+ return comment;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDAndBranchImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDAndBranchImpl.java
new file mode 100644
index 0000000000..6ab18f3155
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDAndBranchImpl.java
@@ -0,0 +1,87 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.internal.common.id;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDAndBranch;
+import org.eclipse.emf.cdo.common.io.CDODataInput;
+import org.eclipse.emf.cdo.common.io.CDODataOutput;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOIDAndBranchImpl implements CDOIDAndBranch
+{
+ private CDOID id;
+
+ private CDOBranch branch;
+
+ public CDOIDAndBranchImpl(CDOID id, CDOBranch branch)
+ {
+ this.id = id;
+ this.branch = branch;
+ }
+
+ public CDOIDAndBranchImpl(CDODataInput in) throws IOException
+ {
+ id = in.readCDOID();
+ branch = in.readCDOBranch();
+ }
+
+ public void write(CDODataOutput out) throws IOException
+ {
+ out.writeCDOID(id);
+ out.writeCDOBranch(branch);
+ }
+
+ public CDOID getID()
+ {
+ return id;
+ }
+
+ public CDOBranch getBranch()
+ {
+ return branch;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+
+ if (obj instanceof CDOIDAndBranch)
+ {
+ CDOIDAndBranch that = (CDOIDAndBranch)obj;
+ return id.equals(that.getID()) && branch.equals(that.getBranch());
+ }
+
+ return false;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return id.hashCode() ^ branch.hashCode();
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("{0}:{1}", id, branch.getID()); //$NON-NLS-1$
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDAndVersionAndBranchImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDAndVersionAndBranchImpl.java
new file mode 100644
index 0000000000..45561844a7
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDAndVersionAndBranchImpl.java
@@ -0,0 +1,80 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.internal.common.id;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDAndVersionAndBranch;
+import org.eclipse.emf.cdo.common.io.CDODataInput;
+import org.eclipse.emf.cdo.common.io.CDODataOutput;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+
+/**
+ * @author Eike Stepper
+ */
+public final class CDOIDAndVersionAndBranchImpl extends CDOIDAndVersionImpl implements CDOIDAndVersionAndBranch
+{
+ private int branchID;
+
+ public CDOIDAndVersionAndBranchImpl(CDOID id, int version, int branchID)
+ {
+ super(id, version);
+ this.branchID = branchID;
+ }
+
+ public CDOIDAndVersionAndBranchImpl(CDODataInput in) throws IOException
+ {
+ super(in);
+ branchID = in.readInt();
+ }
+
+ @Override
+ public void write(CDODataOutput out) throws IOException
+ {
+ super.write(out);
+ out.writeInt(branchID);
+ }
+
+ public int getBranchID()
+ {
+ return branchID;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+
+ if (obj instanceof CDOIDAndVersionAndBranch)
+ {
+ CDOIDAndVersionAndBranch that = (CDOIDAndVersionAndBranch)obj;
+ return getID().equals(that.getID()) && getVersion() == that.getVersion() && branchID == that.getBranchID();
+ }
+
+ return false;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return getID().hashCode() ^ getVersion() ^ branchID;
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("{0}v{1}b{2}", getID(), getVersion(), branchID); //$NON-NLS-1$
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDAndVersionImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDAndVersionImpl.java
index 67f9874b45..2a26ff154e 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDAndVersionImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDAndVersionImpl.java
@@ -4,7 +4,7 @@
* 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
*/
@@ -21,7 +21,7 @@ import java.text.MessageFormat;
/**
* @author Eike Stepper
*/
-public final class CDOIDAndVersionImpl implements CDOIDAndVersion
+public class CDOIDAndVersionImpl implements CDOIDAndVersion
{
private CDOID id;
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/io/CDODataInputImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/io/CDODataInputImpl.java
index 89931de7b3..bbe18c6bc4 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/io/CDODataInputImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/io/CDODataInputImpl.java
@@ -11,8 +11,14 @@
*/
package org.eclipse.emf.cdo.internal.common.io;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchManager;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDAndBranch;
import org.eclipse.emf.cdo.common.id.CDOIDAndVersion;
+import org.eclipse.emf.cdo.common.id.CDOIDAndVersionAndBranch;
import org.eclipse.emf.cdo.common.id.CDOIDMetaRange;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.id.CDOID.Type;
@@ -31,6 +37,8 @@ import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.internal.common.bundle.OM;
+import org.eclipse.emf.cdo.internal.common.id.CDOIDAndBranchImpl;
+import org.eclipse.emf.cdo.internal.common.id.CDOIDAndVersionAndBranchImpl;
import org.eclipse.emf.cdo.internal.common.id.CDOIDAndVersionImpl;
import org.eclipse.emf.cdo.internal.common.id.CDOIDExternalImpl;
import org.eclipse.emf.cdo.internal.common.id.CDOIDMetaImpl;
@@ -49,6 +57,7 @@ import org.eclipse.emf.cdo.internal.common.revision.delta.CDORemoveFeatureDeltaI
import org.eclipse.emf.cdo.internal.common.revision.delta.CDORevisionDeltaImpl;
import org.eclipse.emf.cdo.internal.common.revision.delta.CDOSetFeatureDeltaImpl;
import org.eclipse.emf.cdo.internal.common.revision.delta.CDOUnsetFeatureDeltaImpl;
+import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
import org.eclipse.emf.cdo.spi.common.id.AbstractCDOID;
import org.eclipse.emf.cdo.spi.common.id.InternalCDOIDObject;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo;
@@ -147,6 +156,26 @@ public abstract class CDODataInputImpl extends ExtendedDataInput.Delegating impl
return CDOModelUtil.getType(typeID);
}
+ public CDOBranch readCDOBranch() throws IOException
+ {
+ int branchID = readInt();
+ return getBranchManager().getBranch(branchID);
+ }
+
+ public CDOBranchPoint readCDOBranchPoint() throws IOException
+ {
+ CDOBranch branch = readCDOBranch();
+ long timeStamp = readLong();
+ return CDOBranchUtil.createBranchPoint(branch, timeStamp);
+ }
+
+ public CDOBranchVersion readCDOBranchVersion() throws IOException
+ {
+ CDOBranch branch = readCDOBranch();
+ int version = readInt();
+ return CDOBranchUtil.createBranchVersion(branch, version);
+ }
+
public CDOID readCDOID() throws IOException
{
byte ordinal = readByte();
@@ -239,6 +268,16 @@ public abstract class CDODataInputImpl extends ExtendedDataInput.Delegating impl
return new CDOIDAndVersionImpl(this);
}
+ public CDOIDAndBranch readCDOIDAndBranch() throws IOException
+ {
+ return new CDOIDAndBranchImpl(this);
+ }
+
+ public CDOIDAndVersionAndBranch readCDOIDAndVersionAndBranch() throws IOException
+ {
+ return new CDOIDAndVersionAndBranchImpl(this);
+ }
+
public CDOIDMetaRange readCDOIDMetaRange() throws IOException
{
boolean exist = readBoolean();
@@ -394,6 +433,8 @@ public abstract class CDODataInputImpl extends ExtendedDataInput.Delegating impl
protected abstract CDOPackageRegistry getPackageRegistry();
+ protected abstract CDOBranchManager getBranchManager();
+
protected abstract CDORevisionFactory getRevisionFactory();
protected abstract CDOListFactory getListFactory();
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/io/CDODataOutputImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/io/CDODataOutputImpl.java
index d6fc4bbbfb..a6c31da81b 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/io/CDODataOutputImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/io/CDODataOutputImpl.java
@@ -10,8 +10,13 @@
*/
package org.eclipse.emf.cdo.internal.common.io;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDAndBranch;
import org.eclipse.emf.cdo.common.id.CDOIDAndVersion;
+import org.eclipse.emf.cdo.common.id.CDOIDAndVersionAndBranch;
import org.eclipse.emf.cdo.common.id.CDOIDMetaRange;
import org.eclipse.emf.cdo.common.id.CDOIDProvider;
import org.eclipse.emf.cdo.common.io.CDODataOutput;
@@ -26,6 +31,8 @@ import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.internal.common.bundle.OM;
+import org.eclipse.emf.cdo.internal.common.id.CDOIDAndBranchImpl;
+import org.eclipse.emf.cdo.internal.common.id.CDOIDAndVersionAndBranchImpl;
import org.eclipse.emf.cdo.internal.common.id.CDOIDAndVersionImpl;
import org.eclipse.emf.cdo.internal.common.messages.Messages;
import org.eclipse.emf.cdo.internal.common.model.CDOTypeImpl;
@@ -115,6 +122,23 @@ public abstract class CDODataOutputImpl extends ExtendedDataOutput.Delegating im
((CDOTypeImpl)cdoType).write(this);
}
+ public void writeCDOBranch(CDOBranch branch) throws IOException
+ {
+ writeInt(branch.getID());
+ }
+
+ public void writeCDOBranchPoint(CDOBranchPoint branchPoint) throws IOException
+ {
+ writeCDOBranch(branchPoint.getBranch());
+ writeLong(branchPoint.getTimeStamp());
+ }
+
+ public void writeCDOBranchVersion(CDOBranchVersion branchVersion) throws IOException
+ {
+ writeCDOBranch(branchVersion.getBranch());
+ writeInt(branchVersion.getVersion());
+ }
+
public void writeCDOID(CDOID id) throws IOException
{
if (id == null)
@@ -155,6 +179,16 @@ public abstract class CDODataOutputImpl extends ExtendedDataOutput.Delegating im
((CDOIDAndVersionImpl)idAndVersion).write(this);
}
+ public void writeCDOIDAndBranch(CDOIDAndBranch idAndBranch) throws IOException
+ {
+ ((CDOIDAndBranchImpl)idAndBranch).write(this);
+ }
+
+ public void writeCDOIDAndVersionAndBranch(CDOIDAndVersionAndBranch idAndVersionAndBranch) throws IOException
+ {
+ ((CDOIDAndVersionAndBranchImpl)idAndVersionAndBranch).write(this);
+ }
+
public void writeCDOIDMetaRange(CDOIDMetaRange metaRange) throws IOException
{
if (metaRange == null)
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPackageUnitImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPackageUnitImpl.java
index 6d2841c4a1..430ed1ff2c 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPackageUnitImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPackageUnitImpl.java
@@ -4,7 +4,7 @@
* 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
*/
@@ -311,7 +311,7 @@ public class CDOPackageUnitImpl implements InternalCDOPackageUnit
@Override
public String toString()
{
- String fmt = "CDOPackageUnit[id={0}, state={1}, type={2}, originalType={3}, timeStamp={4,date} {4,time}]"; //$NON-NLS-1$
+ String fmt = "CDOPackageUnit[id={0}, state={1}, type={2}, originalType={3}, timeStamp={4,date} {4,time,HH:mm:ss:SSS}]"; //$NON-NLS-1$
return MessageFormat.format(fmt, getID(), getState(), getType(), getOriginalType(), getTimeStamp());
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionImpl.java
index 59150b0aad..9d203962cb 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionImpl.java
@@ -16,7 +16,7 @@ package org.eclipse.emf.cdo.internal.common.revision;
import org.eclipse.emf.cdo.common.model.CDOModelUtil;
import org.eclipse.emf.cdo.common.model.CDOType;
import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.AbstractCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.BaseCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDOList;
import org.eclipse.emf.ecore.EClass;
@@ -26,7 +26,7 @@ import org.eclipse.emf.ecore.EStructuralFeature;
/**
* @author Eike Stepper
*/
-public class CDORevisionImpl extends AbstractCDORevision
+public class CDORevisionImpl extends BaseCDORevision
{
private Object[] values;
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionKeyImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionKeyImpl.java
new file mode 100644
index 0000000000..74f1e37c26
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionKeyImpl.java
@@ -0,0 +1,66 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.internal.common.revision;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
+import org.eclipse.emf.cdo.internal.common.branch.CDOBranchVersionImpl;
+
+import java.text.MessageFormat;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDORevisionKeyImpl extends CDOBranchVersionImpl implements CDORevisionKey
+{
+ private CDOID id;
+
+ public CDORevisionKeyImpl(CDOID id, CDOBranch branch, int version)
+ {
+ super(branch, version);
+ this.id = id;
+ }
+
+ public CDOID getID()
+ {
+ return id;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return id.hashCode() ^ super.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+
+ if (obj instanceof CDORevisionKey)
+ {
+ CDORevisionKey that = (CDORevisionKey)obj;
+ return id.equals(that.getID()) && getBranch().equals(that.getBranch()) && getVersion() == that.getVersion();
+ }
+
+ return false;
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("{0}:{1}v{2}", id, getBranch().getID(), getVersion());
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionManagerImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionManagerImpl.java
index a70df6d587..f36b718524 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionManagerImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionManagerImpl.java
@@ -12,14 +12,23 @@
*/
package org.eclipse.emf.cdo.internal.common.revision;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionFactory;
import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCache;
import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCacheUtil;
+import org.eclipse.emf.cdo.common.revision.cache.InternalCDORevisionCache;
import org.eclipse.emf.cdo.internal.common.bundle.OM;
+import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
+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.InternalCDORevisionManager;
+import org.eclipse.emf.cdo.spi.common.revision.PointerCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.RevisionInfo;
+import org.eclipse.emf.cdo.spi.common.revision.SyntheticCDORevision;
import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
import org.eclipse.net4j.util.lifecycle.Lifecycle;
@@ -29,9 +38,10 @@ import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.emf.ecore.EClass;
import java.util.ArrayList;
-import java.util.Collection;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* @author Eike Stepper
@@ -40,24 +50,40 @@ public class CDORevisionManagerImpl extends Lifecycle implements InternalCDORevi
{
private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REVISION, CDORevisionManagerImpl.class);
+ private boolean supportingBranches;
+
private RevisionLoader revisionLoader;
private RevisionLocker revisionLocker;
private CDORevisionFactory factory;
- private CDORevisionCache cache;
+ private InternalCDORevisionCache cache;
+
+ @ExcludeFromDump
+ private transient Object loadAndAddLock = new Object();
@ExcludeFromDump
- private Object loadAndAddLock = new Object();
+ private transient Object revisedLock = new Object();
@ExcludeFromDump
- private Object revisedLock = new Object();
+ private transient AtomicInteger loadCounterForTest;
public CDORevisionManagerImpl()
{
}
+ public boolean isSupportingBranches()
+ {
+ return supportingBranches;
+ }
+
+ public void setSupportingBranches(boolean on)
+ {
+ checkInactive();
+ supportingBranches = on;
+ }
+
public RevisionLoader getRevisionLoader()
{
return revisionLoader;
@@ -65,6 +91,7 @@ public class CDORevisionManagerImpl extends Lifecycle implements InternalCDORevi
public void setRevisionLoader(RevisionLoader revisionLoader)
{
+ checkInactive();
this.revisionLoader = revisionLoader;
}
@@ -75,6 +102,7 @@ public class CDORevisionManagerImpl extends Lifecycle implements InternalCDORevi
public void setRevisionLocker(RevisionLocker revisionLocker)
{
+ checkInactive();
this.revisionLocker = revisionLocker;
}
@@ -85,50 +113,51 @@ public class CDORevisionManagerImpl extends Lifecycle implements InternalCDORevi
public void setFactory(CDORevisionFactory factory)
{
+ checkInactive();
this.factory = factory;
}
- public CDORevisionCache getCache()
+ public InternalCDORevisionCache getCache()
{
return cache;
}
public void setCache(CDORevisionCache cache)
{
- this.cache = cache;
+ checkInactive();
+ this.cache = (InternalCDORevisionCache)cache;
}
- public boolean containsRevision(CDOID id)
+ public EClass getObjectType(CDOID id)
{
- return cache.getRevision(id) != null;
+ return cache.getObjectType(id);
}
- public boolean containsRevisionByTime(CDOID id, long timeStamp)
+ public boolean containsRevision(CDOID id, CDOBranchPoint branchPoint)
{
- return cache.getRevisionByTime(id, timeStamp) != null;
- }
+ if (supportingBranches)
+ {
+ return getRevision(id, branchPoint, CDORevision.UNCHUNKED, CDORevision.DEPTH_NONE, false, null) != null;
+ }
- public boolean containsRevisionByVersion(CDOID id, int version)
- {
- return cache.getRevisionByVersion(id, version) != null;
+ return getCachedRevision(id, branchPoint) != null;
}
- public EClass getObjectType(CDOID id)
+ public boolean containsRevisionByVersion(CDOID id, CDOBranchVersion branchVersion)
{
- return cache.getObjectType(id);
+ return cache.getRevisionByVersion(id, branchVersion) != null;
}
- public void reviseLatest(CDOID id)
+ public void reviseLatest(CDOID id, CDOBranch branch)
{
acquireAtomicRequestLock(revisedLock);
try
{
- // TODO Consider CDORevisionCache.removeLatestRevision()
- InternalCDORevision revision = (InternalCDORevision)cache.getRevision(id);
+ InternalCDORevision revision = (InternalCDORevision)cache.getRevision(id, branch.getHead());
if (revision != null)
{
- cache.removeRevision(revision.getID(), revision.getVersion());
+ cache.removeRevision(id, branch.getVersion(revision.getVersion()));
}
}
finally
@@ -137,18 +166,18 @@ public class CDORevisionManagerImpl extends Lifecycle implements InternalCDORevi
}
}
- public void reviseVersion(CDOID id, int version, long timeStamp)
+ public void reviseVersion(CDOID id, CDOBranchVersion branchVersion, long timeStamp)
{
acquireAtomicRequestLock(revisedLock);
try
{
- InternalCDORevision revision = (InternalCDORevision)cache.getRevisionByVersion(id, version);
+ InternalCDORevision revision = getCachedRevisionByVersion(id, branchVersion);
if (revision != null)
{
if (timeStamp == CDORevision.UNSPECIFIED_DATE)
{
- cache.removeRevision(revision.getID(), revision.getVersion());
+ cache.removeRevision(id, branchVersion);
}
else
{
@@ -162,39 +191,26 @@ public class CDORevisionManagerImpl extends Lifecycle implements InternalCDORevi
}
}
- public InternalCDORevision getRevision(CDOID id, int referenceChunk, int prefetchDepth)
- {
- return getRevision(id, referenceChunk, prefetchDepth, true);
- }
-
- public InternalCDORevision getRevision(CDOID id, int referenceChunk, int prefetchDepth, boolean loadOnDemand)
+ public InternalCDORevision getRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int referenceChunk,
+ boolean loadOnDemand)
{
+ checkArg(branchVersion.getVersion() > 0, "Invalid version: " + branchVersion.getVersion());
acquireAtomicRequestLock(loadAndAddLock);
try
{
- boolean prefetch = prefetchDepth != CDORevision.DEPTH_NONE;
- InternalCDORevision revision = prefetch ? null : (InternalCDORevision)cache.getRevision(id);
+ InternalCDORevision revision = getCachedRevisionByVersion(id, branchVersion);
if (revision == null)
{
if (loadOnDemand)
{
if (TRACER.isEnabled())
{
- TRACER.format("Loading revision {0}", id); //$NON-NLS-1$
+ TRACER.format("Loading revision {0} from {1}", id, branchVersion); //$NON-NLS-1$
}
- revision = revisionLoader.loadRevision(id, referenceChunk, prefetchDepth);
- addCachedRevisionIfNotNull(revision);
- }
- }
- else
- {
- InternalCDORevision oldRevision = revision;
- revision = verifyRevision(oldRevision, referenceChunk);
- if (revision != oldRevision)
- {
- addCachedRevisionIfNotNull(revision);
+ revision = revisionLoader.loadRevisionByVersion(id, branchVersion, referenceChunk);
+ addRevision(revision);
}
}
@@ -206,167 +222,193 @@ public class CDORevisionManagerImpl extends Lifecycle implements InternalCDORevi
}
}
- public InternalCDORevision getRevisionByTime(CDOID id, int referenceChunk, int prefetchDepth, long timeStamp)
+ public CDORevision getRevision(CDOID id, CDOBranchPoint branchPoint, int referenceChunk, int prefetchDepth,
+ boolean loadOnDemand)
{
- return getRevisionByTime(id, referenceChunk, prefetchDepth, timeStamp, true);
+ return getRevision(id, branchPoint, referenceChunk, prefetchDepth, loadOnDemand, null);
}
- public InternalCDORevision getRevisionByTime(CDOID id, int referenceChunk, int prefetchDepth, long timeStamp,
- boolean loadOnDemand)
+ public InternalCDORevision getRevision(CDOID id, CDOBranchPoint branchPoint, int referenceChunk, int prefetchDepth,
+ boolean loadOnDemand, SyntheticCDORevision[] synthetics)
{
- acquireAtomicRequestLock(loadAndAddLock);
-
- try
- {
- boolean prefetch = prefetchDepth != CDORevision.DEPTH_NONE;
- InternalCDORevision revision = prefetch ? null : (InternalCDORevision)cache.getRevisionByTime(id, timeStamp);
- if (revision == null || prefetchDepth != CDORevision.DEPTH_NONE)
- {
- if (loadOnDemand)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Loading revision {0} by time {1,date} {1,time}", id, timeStamp); //$NON-NLS-1$
- }
+ List<CDOID> ids = Collections.singletonList(id);
+ List<CDORevision> revisions = getRevisions(ids, branchPoint, referenceChunk, prefetchDepth, loadOnDemand,
+ synthetics);
+ return (InternalCDORevision)revisions.get(0);
+ }
- revision = revisionLoader.loadRevisionByTime(id, referenceChunk, prefetchDepth, timeStamp);
- addCachedRevisionIfNotNull(revision);
- }
- }
- else
- {
- InternalCDORevision verified = verifyRevision(revision, referenceChunk);
- if (revision != verified)
- {
- addCachedRevisionIfNotNull(verified);
- revision = verified;
- }
- }
+ public List<CDORevision> getRevisions(List<CDOID> ids, CDOBranchPoint branchPoint, int referenceChunk,
+ int prefetchDepth, boolean loadOnDemand)
+ {
+ return getRevisions(ids, branchPoint, referenceChunk, prefetchDepth, loadOnDemand, null);
+ }
- return revision;
- }
- finally
+ public List<CDORevision> getRevisions(List<CDOID> ids, CDOBranchPoint branchPoint, int referenceChunk,
+ int prefetchDepth, boolean loadOnDemand, SyntheticCDORevision[] synthetics)
+ {
+ RevisionInfo[] infos = new RevisionInfo[ids.size()];
+ List<RevisionInfo> infosToLoad = createRevisionInfos(ids, branchPoint, loadOnDemand, infos);
+ if (infosToLoad != null)
{
- releaseAtomicRequestLock(loadAndAddLock);
+ loadRevisions(infosToLoad, branchPoint, referenceChunk, prefetchDepth);
}
- }
- public synchronized InternalCDORevision getRevisionByVersion(CDOID id, int referenceChunk, int prefetchDepth,
- int version)
- {
- return getRevisionByVersion(id, referenceChunk, prefetchDepth, version, true);
+ return getResultsAndSynthetics(infos, synthetics);
}
- public InternalCDORevision getRevisionByVersion(CDOID id, int referenceChunk, int prefetchDepth, int version,
- boolean loadOnDemand)
+ private List<RevisionInfo> createRevisionInfos(List<CDOID> ids, CDOBranchPoint branchPoint, boolean loadOnDemand,
+ RevisionInfo[] infos)
{
- acquireAtomicRequestLock(loadAndAddLock);
-
- try
+ List<RevisionInfo> infosToLoad = null;
+ Iterator<CDOID> idIterator = ids.iterator();
+ for (int i = 0; i < infos.length; i++)
{
- boolean prefetch = prefetchDepth != CDORevision.DEPTH_NONE;
- InternalCDORevision revision = prefetch ? null : (InternalCDORevision)cache.getRevisionByVersion(id, version);
- if (revision == null)
+ CDOID id = idIterator.next();
+ RevisionInfo info = createRevisionInfo(id, branchPoint);
+ infos[i] = info;
+
+ if (info.isLoadNeeded() && loadOnDemand)
{
- if (loadOnDemand)
+ if (infosToLoad == null)
{
- if (TRACER.isEnabled())
- {
- TRACER.format("Loading revision {0} by version {1}", id, version); //$NON-NLS-1$
- }
-
- revision = revisionLoader.loadRevisionByVersion(id, referenceChunk, prefetchDepth, version);
- addCachedRevisionIfNotNull(revision);
+ infosToLoad = new ArrayList<RevisionInfo>(1);
}
+
+ infosToLoad.add(info);
}
+ }
- return revision;
+ return infosToLoad;
+ }
+
+ private RevisionInfo createRevisionInfo(CDOID id, CDOBranchPoint branchPoint)
+ {
+ InternalCDORevision revision = getCachedRevision(id, branchPoint);
+ if (revision != null)
+ {
+ return createRevisionInfoAvailable(revision, branchPoint);
}
- finally
+
+ if (supportingBranches)
{
- releaseAtomicRequestLock(loadAndAddLock);
+ revision = getCachedRevisionRecursively(id, branchPoint);
+ if (revision != null)
+ {
+ return createRevisionInfoAvailable(revision, branchPoint);
+ }
}
+
+ return createRevisionInfoMissing(id, branchPoint);
}
- public List<CDORevision> getRevisions(Collection<CDOID> ids, int referenceChunk, int prefetchDepth)
+ private RevisionInfo.Available createRevisionInfoAvailable(InternalCDORevision revision,
+ CDOBranchPoint requestedBranchPoint)
{
- List<CDOID> missingIDs = new ArrayList<CDOID>(0);
- List<CDORevision> revisions = new ArrayList<CDORevision>(ids.size());
- for (CDOID id : ids)
+ if (revision instanceof PointerCDORevision)
{
- // TODO Combination of prefetch=true and loadOnDemand=false does not make sense!
- InternalCDORevision revision = getRevision(id, referenceChunk, prefetchDepth, false);
- revisions.add(revision);
- if (revision == null)
+ PointerCDORevision pointer = (PointerCDORevision)revision;
+ CDOBranchVersion target = pointer.getTarget();
+ InternalCDORevision targetRevision = target == null ? null : getCachedRevisionByVersion(pointer.getID(), target);
+ if (targetRevision != null)
{
- missingIDs.add(id);
+ target = targetRevision;
}
+
+ return new RevisionInfo.Available.Pointer(pointer.getID(), requestedBranchPoint, pointer, target);
}
- if (!missingIDs.isEmpty())
+ if (revision instanceof DetachedCDORevision)
{
- acquireAtomicRequestLock(loadAndAddLock);
-
- try
- {
- List<InternalCDORevision> missingRevisions = revisionLoader.loadRevisions(missingIDs, referenceChunk,
- prefetchDepth);
- handleMissingRevisions(revisions, missingRevisions);
- }
- finally
- {
- releaseAtomicRequestLock(loadAndAddLock);
- }
+ DetachedCDORevision detached = (DetachedCDORevision)revision;
+ return new RevisionInfo.Available.Detached(detached.getID(), requestedBranchPoint, detached);
}
- return revisions;
+ return new RevisionInfo.Available.Normal(revision.getID(), requestedBranchPoint, revision);
+ }
+
+ private RevisionInfo.Missing createRevisionInfoMissing(CDOID id, CDOBranchPoint requestedBranchPoint)
+ {
+ return new RevisionInfo.Missing(id, requestedBranchPoint);
}
- public List<CDORevision> getRevisionsByTime(Collection<CDOID> ids, int referenceChunk, int prefetchDepth,
- long timeStamp, boolean loadOnDemand)
+ private void loadRevisions(List<RevisionInfo> infosToLoad, CDOBranchPoint branchPoint, int referenceChunk,
+ int prefetchDepth)
{
- List<CDOID> missingIDs = loadOnDemand ? new ArrayList<CDOID>(0) : null;
- List<CDORevision> revisions = new ArrayList<CDORevision>(ids.size());
- for (CDOID id : ids)
+ if (loadCounterForTest != null)
{
- InternalCDORevision revision = getRevisionByTime(id, referenceChunk, prefetchDepth, timeStamp, false);
- revisions.add(revision);
- if (revision == null && missingIDs != null)
+ for (int i = 0; i < infosToLoad.size(); i++)
{
- missingIDs.add(id);
+ loadCounterForTest.incrementAndGet();
}
}
- if (missingIDs != null && !missingIDs.isEmpty())
+ acquireAtomicRequestLock(loadAndAddLock);
+
+ try
{
- acquireAtomicRequestLock(loadAndAddLock);
+ List<InternalCDORevision> additionalRevisions = //
+ revisionLoader.loadRevisions(infosToLoad, branchPoint, referenceChunk, prefetchDepth);
- try
- {
- List<InternalCDORevision> missingRevisions = revisionLoader.loadRevisionsByTime(missingIDs, referenceChunk,
- prefetchDepth, timeStamp);
- handleMissingRevisions(revisions, missingRevisions);
- }
- finally
+ if (additionalRevisions != null)
{
- releaseAtomicRequestLock(loadAndAddLock);
+ for (InternalCDORevision revision : additionalRevisions)
+ {
+ addRevision(revision);
+ }
}
}
-
- return revisions;
+ finally
+ {
+ releaseAtomicRequestLock(loadAndAddLock);
+ }
}
- private void addCachedRevisionIfNotNull(InternalCDORevision revision)
+ private List<CDORevision> getResultsAndSynthetics(RevisionInfo[] infos, SyntheticCDORevision[] synthetics)
{
- if (revision != null)
+ List<CDORevision> results = new ArrayList<CDORevision>(infos.length);
+ for (int i = 0; i < infos.length; i++)
{
- cache.addRevision(revision);
+ RevisionInfo info = infos[i];
+ info.processResult(this, results, synthetics, i);
}
+
+ return results;
}
- protected InternalCDORevision verifyRevision(InternalCDORevision revision, int referenceChunk)
+ public boolean addRevision(CDORevision revision)
{
- return revision;
+ if (revision != null)
+ {
+ if (revision instanceof PointerCDORevision)
+ {
+ PointerCDORevision pointer = (PointerCDORevision)revision;
+ CDOBranchVersion target = pointer.getTarget();
+ if (target instanceof InternalCDORevision)
+ {
+ revision = new PointerCDORevision(pointer.getID(), pointer.getBranch(), pointer.getRevised(), //
+ CDOBranchUtil.createBranchVersion(target));
+ }
+ }
+
+ boolean added = cache.addRevision(revision);
+ if (added)
+ {
+ int oldVersion = revision.getVersion() - 1;
+ if (oldVersion >= CDORevision.UNSPECIFIED_VERSION)
+ {
+ CDOBranchVersion old = CDOBranchUtil.createBranchVersion(revision.getBranch(), oldVersion);
+ InternalCDORevision oldRevision = getCachedRevisionByVersion(revision.getID(), old);
+ if (oldRevision != null)
+ {
+ oldRevision.setRevised(revision.getTimeStamp() - 1);
+ }
+
+ return true;
+ }
+ }
+ }
+
+ return false;
}
@Override
@@ -380,7 +422,12 @@ public class CDORevisionManagerImpl extends Lifecycle implements InternalCDORevi
if (cache == null)
{
- cache = CDORevisionCacheUtil.createDefaultCache();
+ cache = (InternalCDORevisionCache)CDORevisionCacheUtil.createDefaultCache(supportingBranches);
+ }
+
+ if (supportingBranches && !cache.isSupportingBranches())
+ {
+ throw new IllegalStateException("Revision cache does not support branches");
}
}
@@ -414,18 +461,33 @@ public class CDORevisionManagerImpl extends Lifecycle implements InternalCDORevi
}
}
- private void handleMissingRevisions(List<CDORevision> revisions, List<InternalCDORevision> missingRevisions)
+ private InternalCDORevision getCachedRevisionByVersion(CDOID id, CDOBranchVersion branchVersion)
+ {
+ return (InternalCDORevision)cache.getRevisionByVersion(id, branchVersion);
+ }
+
+ private InternalCDORevision getCachedRevision(CDOID id, CDOBranchPoint branchPoint)
+ {
+ return (InternalCDORevision)cache.getRevision(id, branchPoint);
+ }
+
+ private InternalCDORevision getCachedRevisionRecursively(CDOID id, CDOBranchPoint branchPoint)
{
- Iterator<InternalCDORevision> it = missingRevisions.iterator();
- for (int i = 0; i < revisions.size(); i++)
+ CDOBranch branch = branchPoint.getBranch();
+ if (!branch.isMainBranch())
{
- CDORevision revision = revisions.get(i);
- if (revision == null)
+ CDOBranchPoint base = branch.getBase();
+ InternalCDORevision revision = getCachedRevision(id, base);
+ if (revision != null)
{
- InternalCDORevision missingRevision = it.next();
- revisions.set(i, missingRevision);
- addCachedRevisionIfNotNull(missingRevision);
+ return revision;
}
+
+ // Recurse
+ return getCachedRevisionRecursively(id, base);
}
+
+ // Reached main branch
+ return null;
}
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/EvictionEventImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/EvictionEventImpl.java
index 3a0486fe86..1215c6bc89 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/EvictionEventImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/EvictionEventImpl.java
@@ -10,7 +10,9 @@
*/
package org.eclipse.emf.cdo.internal.common.revision.cache;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCache;
import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCache.EvictionEvent;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
@@ -24,25 +26,12 @@ public class EvictionEventImpl extends Event implements EvictionEvent
{
private static final long serialVersionUID = 1L;
- private CDOID id;
+ private CDORevisionKey key;
- private int version;
-
- private InternalCDORevision revision;
-
- public EvictionEventImpl(CDORevisionCache cache, InternalCDORevision revision)
- {
- super(cache);
- id = revision.getID();
- version = revision.getVersion();
- this.revision = revision;
- }
-
- public EvictionEventImpl(CDORevisionCache cache, CDOID id, int version)
+ public EvictionEventImpl(CDORevisionCache cache, CDORevisionKey key)
{
super(cache);
- this.id = id;
- this.version = version;
+ this.key = key;
}
@Override
@@ -53,16 +42,26 @@ public class EvictionEventImpl extends Event implements EvictionEvent
public CDOID getID()
{
- return id;
+ return key.getID();
+ }
+
+ public CDOBranch getBranch()
+ {
+ return key.getBranch();
}
public int getVersion()
{
- return version;
+ return key.getVersion();
}
public InternalCDORevision getRevision()
{
- return revision;
+ if (key instanceof InternalCDORevision)
+ {
+ return (InternalCDORevision)key;
+ }
+
+ return null;
}
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/branch/BranchDispatcher.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/branch/BranchDispatcher.java
new file mode 100644
index 0000000000..ac42dedbb7
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/branch/BranchDispatcher.java
@@ -0,0 +1,190 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.internal.common.revision.cache.branch;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCache;
+import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCacheFactory;
+import org.eclipse.emf.cdo.common.revision.cache.InternalCDORevisionCache;
+
+import org.eclipse.net4j.util.lifecycle.Lifecycle;
+import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
+
+import org.eclipse.emf.ecore.EClass;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Eike Stepper
+ */
+public class BranchDispatcher extends Lifecycle implements InternalCDORevisionCache
+{
+ private Map<CDOBranch, InternalCDORevisionCache> caches = new HashMap<CDOBranch, InternalCDORevisionCache>();
+
+ private CDORevisionCacheFactory factory;
+
+ public BranchDispatcher()
+ {
+ }
+
+ public InternalCDORevisionCache instantiate(CDORevision revision)
+ {
+ BranchDispatcher cache = new BranchDispatcher();
+ cache.setFactory(factory);
+ return cache;
+ }
+
+ public boolean isSupportingBranches()
+ {
+ return true;
+ }
+
+ public CDORevisionCacheFactory getFactory()
+ {
+ return factory;
+ }
+
+ public void setFactory(CDORevisionCacheFactory factory)
+ {
+ checkInactive();
+ this.factory = factory;
+ }
+
+ public EClass getObjectType(CDOID id)
+ {
+ for (CDORevisionCache cache : getCaches())
+ {
+ EClass type = cache.getObjectType(id);
+ if (type != null)
+ {
+ return type;
+ }
+ }
+
+ return null;
+ }
+
+ public CDORevision getRevision(CDOID id, CDOBranchPoint branchPoint)
+ {
+ CDORevisionCache cache = getCache(branchPoint.getBranch());
+ if (cache == null)
+ {
+ return null;
+ }
+
+ return cache.getRevision(id, branchPoint);
+ }
+
+ public CDORevision getRevisionByVersion(CDOID id, CDOBranchVersion branchVersion)
+ {
+ CDORevisionCache cache = getCache(branchVersion.getBranch());
+ if (cache == null)
+ {
+ return null;
+ }
+
+ return cache.getRevisionByVersion(id, branchVersion);
+ }
+
+ public CDORevision removeRevision(CDOID id, CDOBranchVersion branchVersion)
+ {
+ InternalCDORevisionCache cache = getCache(branchVersion.getBranch());
+ if (cache == null)
+ {
+ return null;
+ }
+
+ return cache.removeRevision(id, branchVersion);
+ }
+
+ public boolean addRevision(CDORevision revision)
+ {
+ InternalCDORevisionCache cache;
+ CDOBranch branch = revision.getBranch();
+ synchronized (caches)
+ {
+ cache = caches.get(branch);
+ if (cache == null)
+ {
+ cache = (InternalCDORevisionCache)factory.createRevisionCache(revision);
+ LifecycleUtil.activate(cache);
+ caches.put(branch, cache);
+ }
+ }
+
+ return cache.addRevision(revision);
+ }
+
+ public List<CDORevision> getCurrentRevisions()
+ {
+ List<CDORevision> result = new ArrayList<CDORevision>();
+ for (CDORevisionCache cache : getCaches())
+ {
+ result.addAll(cache.getCurrentRevisions());
+ }
+
+ return result;
+ }
+
+ public void clear()
+ {
+ for (InternalCDORevisionCache cache : getCaches())
+ {
+ cache.clear();
+ }
+ }
+
+ public Map<CDOBranch, List<CDORevision>> getAllRevisions()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void doBeforeActivate() throws Exception
+ {
+ super.doBeforeActivate();
+ checkState(factory, "factory");
+ }
+
+ @Override
+ protected void doDeactivate() throws Exception
+ {
+ for (CDORevisionCache cache : getCaches())
+ {
+ LifecycleUtil.deactivate(cache);
+ }
+
+ super.doDeactivate();
+ }
+
+ private InternalCDORevisionCache getCache(CDOBranch branch)
+ {
+ synchronized (caches)
+ {
+ return caches.get(branch);
+ }
+ }
+
+ private InternalCDORevisionCache[] getCaches()
+ {
+ synchronized (caches)
+ {
+ return caches.values().toArray(new InternalCDORevisionCache[caches.size()]);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/branch/BranchRevisionCache.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/branch/BranchRevisionCache.java
new file mode 100644
index 0000000000..06c02d0c1a
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/branch/BranchRevisionCache.java
@@ -0,0 +1,500 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ * Simon McDuff - bug 201266
+ * Simon McDuff - bug 230832
+ */
+package org.eclipse.emf.cdo.internal.common.revision.cache.branch;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDAndBranch;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
+import org.eclipse.emf.cdo.common.revision.cache.InternalCDORevisionCache;
+import org.eclipse.emf.cdo.internal.common.bundle.OM;
+import org.eclipse.emf.cdo.internal.common.revision.cache.EvictionEventImpl;
+import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+
+import org.eclipse.net4j.util.CheckUtil;
+import org.eclipse.net4j.util.event.IListener;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+import org.eclipse.net4j.util.ref.KeyedReference;
+import org.eclipse.net4j.util.ref.KeyedSoftReference;
+import org.eclipse.net4j.util.ref.KeyedStrongReference;
+import org.eclipse.net4j.util.ref.ReferenceQueueWorker;
+
+import org.eclipse.emf.ecore.EClass;
+
+import java.lang.ref.Reference;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * @author Eike Stepper
+ */
+public class BranchRevisionCache extends ReferenceQueueWorker<InternalCDORevision> implements InternalCDORevisionCache
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REVISION, BranchRevisionCache.class);
+
+ private static boolean disableGC = false;
+
+ private Map<CDOIDAndBranch, RevisionList> revisionLists = new HashMap<CDOIDAndBranch, RevisionList>();
+
+ public BranchRevisionCache()
+ {
+ }
+
+ public InternalCDORevisionCache instantiate(CDORevision revision)
+ {
+ return new BranchRevisionCache();
+ }
+
+ public boolean isSupportingBranches()
+ {
+ return true;
+ }
+
+ public EClass getObjectType(CDOID id)
+ {
+ synchronized (revisionLists)
+ {
+ for (Entry<CDOIDAndBranch, RevisionList> entry : revisionLists.entrySet())
+ {
+ if (id.equals(entry.getKey().getID()))
+ {
+ RevisionList revisionList = entry.getValue();
+ EClass type = revisionList.getObjectType();
+ if (type != null)
+ {
+ return type;
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public InternalCDORevision getRevision(CDOID id, CDOBranchPoint branchPoint)
+ {
+ RevisionList revisionList = getRevisionList(id, branchPoint.getBranch());
+ if (revisionList != null)
+ {
+ return revisionList.getRevision(branchPoint.getTimeStamp());
+ }
+
+ return null;
+ }
+
+ public InternalCDORevision getRevisionByVersion(CDOID id, CDOBranchVersion branchVersion)
+ {
+ RevisionList revisionList = getRevisionList(id, branchVersion.getBranch());
+ if (revisionList != null)
+ {
+ return revisionList.getRevisionByVersion(branchVersion.getVersion());
+ }
+
+ return null;
+ }
+
+ public List<CDORevision> getCurrentRevisions()
+ {
+ List<CDORevision> currentRevisions = new ArrayList<CDORevision>();
+ synchronized (revisionLists)
+ {
+ for (RevisionList revisionList : revisionLists.values())
+ {
+ InternalCDORevision revision = revisionList.getRevision(CDORevision.UNSPECIFIED_DATE);
+ if (revision != null)
+ {
+ currentRevisions.add(revision);
+ }
+ }
+ }
+
+ return currentRevisions;
+ }
+
+ public boolean addRevision(CDORevision revision)
+ {
+ CheckUtil.checkArg(revision, "revision");
+ CDOIDAndBranch key = CDOIDUtil.createIDAndBranch(revision.getID(), revision.getBranch());
+ synchronized (revisionLists)
+ {
+ RevisionList list = revisionLists.get(key);
+ if (list == null)
+ {
+ list = new RevisionList();
+ revisionLists.put(key, list);
+ }
+
+ InternalCDORevision rev = (InternalCDORevision)revision;
+ return list.addRevision(rev, createReference(key, rev));
+ }
+ }
+
+ public InternalCDORevision removeRevision(CDOID id, CDOBranchVersion branchVersion)
+ {
+ CDOIDAndBranch key = CDOIDUtil.createIDAndBranch(id, branchVersion.getBranch());
+ synchronized (revisionLists)
+ {
+ RevisionList list = revisionLists.get(key);
+ if (list != null)
+ {
+ list.removeRevision(branchVersion.getVersion());
+ if (list.isEmpty())
+ {
+ revisionLists.remove(key);
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Removed cache list of {0}", key); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public void clear()
+ {
+ synchronized (revisionLists)
+ {
+ revisionLists.clear();
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return revisionLists.toString();
+ }
+
+ public Map<CDOBranch, List<CDORevision>> getAllRevisions()
+ {
+ Map<CDOBranch, List<CDORevision>> result = new HashMap<CDOBranch, List<CDORevision>>();
+ for (RevisionList list : revisionLists.values())
+ {
+ list.getAllRevisions(result);
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void work(Reference<? extends InternalCDORevision> reference)
+ {
+ @SuppressWarnings("unchecked")
+ KeyedReference<CDORevisionKey, InternalCDORevision> keyedRef = (KeyedReference<CDORevisionKey, InternalCDORevision>)reference;
+ CDORevisionKey key = keyedRef.getKey();
+
+ CDOID id = key.getID();
+ CDOBranch branch = key.getBranch();
+ int version = key.getVersion();
+
+ InternalCDORevision revision = removeRevision(id, CDOBranchUtil.createBranchVersion(branch, version));
+ if (revision == null)
+ {
+ // Use revision in eviction event
+ key = revision;
+ }
+
+ IListener[] listeners = getListeners();
+ if (listeners != null)
+ {
+ fireEvent(new EvictionEventImpl(this, key), listeners);
+ }
+ }
+
+ private KeyedReference<CDORevisionKey, InternalCDORevision> createReference(CDOIDAndBranch idAndBranch,
+ InternalCDORevision revision)
+ {
+ CDORevisionKey key = new RevisionKey(idAndBranch, revision.getVersion());
+ if (disableGC)
+ {
+ return new KeyedStrongReference<CDORevisionKey, InternalCDORevision>(key, revision);
+ }
+
+ return new KeyedSoftReference<CDORevisionKey, InternalCDORevision>(key, revision, getQueue());
+ }
+
+ private RevisionList getRevisionList(CDOID id, CDOBranch branch)
+ {
+ CDOIDAndBranch key = CDOIDUtil.createIDAndBranch(id, branch);
+ synchronized (revisionLists)
+ {
+ return revisionLists.get(key);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private static final class RevisionKey implements CDORevisionKey
+ {
+ private CDOIDAndBranch idAndBranch;
+
+ private int version;
+
+ public RevisionKey(CDOIDAndBranch idAndBranch, int version)
+ {
+ this.idAndBranch = idAndBranch;
+ this.version = version;
+ }
+
+ public CDOID getID()
+ {
+ return idAndBranch.getID();
+ }
+
+ public CDOBranch getBranch()
+ {
+ return idAndBranch.getBranch();
+ }
+
+ public int getVersion()
+ {
+ return version;
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("{0}:{1}v{2}", getID(), getBranch().getID(), getVersion());
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private static final class RevisionList extends LinkedList<KeyedReference<CDORevisionKey, InternalCDORevision>>
+ {
+ private static final long serialVersionUID = 1L;
+
+ public RevisionList()
+ {
+ }
+
+ public synchronized EClass getObjectType()
+ {
+ for (Iterator<KeyedReference<CDORevisionKey, InternalCDORevision>> it = iterator(); it.hasNext();)
+ {
+ KeyedReference<CDORevisionKey, InternalCDORevision> ref = it.next();
+ InternalCDORevision revision = ref.get();
+ if (revision != null)
+ {
+ EClass type = revision.getEClass();
+ if (type != null)
+ {
+ return type;
+ }
+ }
+
+ it.remove();
+ }
+
+ return null;
+ }
+
+ public synchronized InternalCDORevision getRevision(long timeStamp)
+ {
+ if (timeStamp == CDORevision.UNSPECIFIED_DATE)
+ {
+ KeyedReference<CDORevisionKey, InternalCDORevision> ref = isEmpty() ? null : getFirst();
+ if (ref != null)
+ {
+ InternalCDORevision revision = ref.get();
+ if (revision != null)
+ {
+ if (!revision.isHistorical())
+ {
+ return revision;
+ }
+ }
+ else
+ {
+ removeFirst();
+ }
+ }
+
+ return null;
+ }
+
+ for (Iterator<KeyedReference<CDORevisionKey, InternalCDORevision>> it = iterator(); it.hasNext();)
+ {
+ KeyedReference<CDORevisionKey, InternalCDORevision> ref = it.next();
+ InternalCDORevision revision = ref.get();
+ if (revision != null)
+ {
+ long created = revision.getTimeStamp();
+ if (created <= timeStamp)
+ {
+ long revised = revision.getRevised();
+ if (timeStamp <= revised || revised == CDORevision.UNSPECIFIED_DATE)
+ {
+ return revision;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ it.remove();
+ }
+ }
+
+ return null;
+ }
+
+ public synchronized InternalCDORevision getRevisionByVersion(int version)
+ {
+ for (Iterator<KeyedReference<CDORevisionKey, InternalCDORevision>> it = iterator(); it.hasNext();)
+ {
+ KeyedReference<CDORevisionKey, InternalCDORevision> ref = it.next();
+ InternalCDORevision revision = ref.get();
+ if (revision != null)
+ {
+ int v = revision.getVersion();
+ if (v == version)
+ {
+ return revision;
+ }
+ else if (v < version)
+ {
+ break;
+ }
+ }
+ else
+ {
+ it.remove();
+ }
+ }
+
+ return null;
+ }
+
+ public synchronized boolean addRevision(InternalCDORevision revision,
+ KeyedReference<CDORevisionKey, InternalCDORevision> reference)
+ {
+ int version = revision.getVersion();
+ for (ListIterator<KeyedReference<CDORevisionKey, InternalCDORevision>> it = listIterator(); it.hasNext();)
+ {
+ KeyedReference<CDORevisionKey, InternalCDORevision> ref = it.next();
+ InternalCDORevision foundRevision = ref.get();
+ if (foundRevision != null)
+ {
+ CDORevisionKey key = ref.getKey();
+ int v = key.getVersion();
+ if (v == version)
+ {
+ return false;
+ }
+
+ if (v < version)
+ {
+ it.previous();
+ it.add(reference);
+ return true;
+ }
+ }
+ else
+ {
+ it.remove();
+ }
+ }
+
+ addLast(reference);
+ return true;
+ }
+
+ public synchronized void removeRevision(int version)
+ {
+ for (Iterator<KeyedReference<CDORevisionKey, InternalCDORevision>> it = iterator(); it.hasNext();)
+ {
+ KeyedReference<CDORevisionKey, InternalCDORevision> ref = it.next();
+ CDORevisionKey key = ref.getKey();
+ int v = key.getVersion();
+ if (v == version)
+ {
+ it.remove();
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Removed version {0} from cache list of {1}", version, key.getID()); //$NON-NLS-1$
+ }
+
+ break;
+ }
+ else if (v < version)
+ {
+ break;
+ }
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuffer buffer = new StringBuffer();
+ for (Iterator<KeyedReference<CDORevisionKey, InternalCDORevision>> it = iterator(); it.hasNext();)
+ {
+ KeyedReference<CDORevisionKey, InternalCDORevision> ref = it.next();
+ InternalCDORevision revision = ref.get();
+ if (buffer.length() == 0)
+ {
+ buffer.append("{");
+ }
+ else
+ {
+ buffer.append(", ");
+ }
+
+ buffer.append(revision);
+ }
+
+ buffer.append("}");
+ return buffer.toString();
+ }
+
+ public void getAllRevisions(Map<CDOBranch, List<CDORevision>> result)
+ {
+ for (Iterator<KeyedReference<CDORevisionKey, InternalCDORevision>> it = iterator(); it.hasNext();)
+ {
+ KeyedReference<CDORevisionKey, InternalCDORevision> ref = it.next();
+ InternalCDORevision revision = ref.get();
+ if (revision != null)
+ {
+ CDOBranch branch = revision.getBranch();
+ List<CDORevision> resultList = result.get(branch);
+ if (resultList == null)
+ {
+ resultList = new ArrayList<CDORevision>(1);
+ result.put(branch, resultList);
+ }
+
+ resultList.add(revision);
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/lru/LRURevisionCache.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/lru/LRURevisionCache.java
index 8b219a1ecb..17567247f2 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/lru/LRURevisionCache.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/lru/LRURevisionCache.java
@@ -11,9 +11,12 @@
*/
package org.eclipse.emf.cdo.internal.common.revision.cache.lru;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCache;
+import org.eclipse.emf.cdo.common.revision.cache.InternalCDORevisionCache;
import org.eclipse.emf.cdo.internal.common.bundle.OM;
import org.eclipse.emf.cdo.internal.common.revision.cache.EvictionEventImpl;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
@@ -34,7 +37,7 @@ import java.util.Map;
/**
* @author Eike Stepper
*/
-public class LRURevisionCache extends Lifecycle implements CDORevisionCache
+public class LRURevisionCache extends Lifecycle implements InternalCDORevisionCache
{
private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REVISION, LRURevisionCache.class);
@@ -52,6 +55,19 @@ public class LRURevisionCache extends Lifecycle implements CDORevisionCache
{
}
+ public InternalCDORevisionCache instantiate(CDORevision revision)
+ {
+ LRURevisionCache cache = new LRURevisionCache();
+ cache.setCapacityCurrent(capacityCurrent);
+ cache.setCapacityRevised(capacityRevised);
+ return cache;
+ }
+
+ public boolean isSupportingBranches()
+ {
+ return false;
+ }
+
public int getCapacityCurrent()
{
return capacityCurrent;
@@ -88,13 +104,13 @@ public class LRURevisionCache extends Lifecycle implements CDORevisionCache
}
}
- public synchronized List<CDORevision> getRevisions()
+ public synchronized List<CDORevision> getCurrentRevisions()
{
List<CDORevision> currentRevisions = new ArrayList<CDORevision>();
for (RevisionHolder holder : revisions.values())
{
InternalCDORevision revision = holder.getRevision();
- if (revision != null && revision.isCurrent())
+ if (revision != null && !revision.isHistorical())
{
currentRevisions.add(revision);
}
@@ -115,30 +131,19 @@ public class LRURevisionCache extends Lifecycle implements CDORevisionCache
return revision.getEClass();
}
- public synchronized InternalCDORevision getRevision(CDOID id)
+ public synchronized InternalCDORevision getRevision(CDOID id, CDOBranchPoint branchPoint)
{
RevisionHolder holder = getHolder(id);
- InternalCDORevision revision = holder == null ? null : holder.getRevision();
- if (revision == null || !revision.isCurrent())
- {
- return null;
- }
-
- return revision;
+ return getRevision(holder, branchPoint.getTimeStamp());
}
- public synchronized InternalCDORevision getRevisionByTime(CDOID id, long timeStamp)
- {
- RevisionHolder holder = getHolder(id);
- return getRevisionByTime(holder, timeStamp);
- }
-
- public synchronized InternalCDORevision getRevisionByVersion(CDOID id, int version)
+ public synchronized InternalCDORevision getRevisionByVersion(CDOID id, CDOBranchVersion branchVersion)
{
RevisionHolder holder = getHolder(id);
while (holder != null)
{
int holderVersion = holder.getVersion();
+ int version = branchVersion.getVersion();
if (holderVersion > version)
{
holder = holder.getNext();
@@ -161,8 +166,10 @@ public class LRURevisionCache extends Lifecycle implements CDORevisionCache
CheckUtil.checkArg(revision, "revision");
if (TRACER.isEnabled())
{
- TRACER.format("Adding revision: {0}, created={1,date} {1,time}, revised={2,date} {2,time}, current={3}", //$NON-NLS-1$
- revision, revision.getCreated(), revision.getRevised(), revision.isCurrent());
+ TRACER
+ .format(
+ "Adding revision: {0}, timeStamp={1,date} {1,time,HH:mm:ss:SSS}, revised={2,date} {2,time,HH:mm:ss:SSS}, historical={3}", //$NON-NLS-1$
+ revision, revision.getTimeStamp(), revision.getRevised(), revision.isHistorical());
}
int version = revision.getVersion();
@@ -188,25 +195,21 @@ public class LRURevisionCache extends Lifecycle implements CDORevisionCache
// Create holder only if require
RevisionHolder newHolder = createHolder((InternalCDORevision)revision);
- LRU list = revision.isCurrent() ? currentLRU : revisedLRU;
+ LRU list = revision.isHistorical() ? revisedLRU : currentLRU;
list.add((DLRevisionHolder)newHolder);
adjustHolder((InternalCDORevision)revision, newHolder, lastHolder, holder);
return true;
}
- public synchronized void removeRevision(CDORevision revision)
- {
- removeRevision(revision.getID(), revision.getVersion());
- }
-
- public synchronized InternalCDORevision removeRevision(CDOID id, int version)
+ public synchronized InternalCDORevision removeRevision(CDOID id, CDOBranchVersion branchVersion)
{
InternalCDORevision revision = null;
RevisionHolder holder = getHolder(id);
while (holder != null)
{
int holderVersion = holder.getVersion();
+ int version = branchVersion.getVersion();
if (holderVersion > version)
{
holder = holder.getNext();
@@ -216,7 +219,7 @@ public class LRURevisionCache extends Lifecycle implements CDORevisionCache
if (holderVersion == version)
{
revision = holder.getRevision();
- LRU list = revision.isCurrent() ? currentLRU : revisedLRU;
+ LRU list = revision.isHistorical() ? revisedLRU : currentLRU;
list.remove((DLRevisionHolder)holder);
removeHolder(holder);
}
@@ -228,7 +231,7 @@ public class LRURevisionCache extends Lifecycle implements CDORevisionCache
return revision;
}
- public synchronized boolean removeRevisions(CDOID id)
+ public synchronized boolean removeRevisions(CDOID id, CDOBranch branch)
{
RevisionHolder lookupHolder = getHolder(id);
RevisionHolder holder = lookupHolder;
@@ -249,7 +252,12 @@ public class LRURevisionCache extends Lifecycle implements CDORevisionCache
revisedLRU = new LRU(capacityRevised);
}
- private InternalCDORevision getRevisionByTime(RevisionHolder holder, long timeStamp)
+ public Map<CDOBranch, List<CDORevision>> getAllRevisions()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ private InternalCDORevision getRevision(RevisionHolder holder, long timeStamp)
{
while (holder != null)
{
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/lru/RevisionHolder.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/lru/RevisionHolder.java
index 2b82146b30..afb658cb57 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/lru/RevisionHolder.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/lru/RevisionHolder.java
@@ -4,7 +4,7 @@
* 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
*/
@@ -44,7 +44,7 @@ public class RevisionHolder
public long getCreated()
{
- return revision.getCreated();
+ return revision.getTimeStamp();
}
public long getRevised()
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/mem/MEMRevisionCache.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/mem/MEMRevisionCache.java
index 7fc2afcc38..5496c419b7 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/mem/MEMRevisionCache.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/mem/MEMRevisionCache.java
@@ -12,14 +12,19 @@
*/
package org.eclipse.emf.cdo.internal.common.revision.cache.mem;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
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.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCache;
+import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
+import org.eclipse.emf.cdo.common.revision.cache.InternalCDORevisionCache;
import org.eclipse.emf.cdo.internal.common.bundle.OM;
import org.eclipse.emf.cdo.internal.common.messages.Messages;
import org.eclipse.emf.cdo.internal.common.revision.cache.EvictionEventImpl;
+import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.net4j.util.CheckUtil;
@@ -49,7 +54,7 @@ import java.util.Map.Entry;
/**
* @author Eike Stepper
*/
-public class MEMRevisionCache extends ReferenceQueueWorker<InternalCDORevision> implements CDORevisionCache
+public class MEMRevisionCache extends ReferenceQueueWorker<InternalCDORevision> implements InternalCDORevisionCache
{
private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REVISION, MEMRevisionCache.class);
@@ -59,7 +64,7 @@ public class MEMRevisionCache extends ReferenceQueueWorker<InternalCDORevision>
public MEMRevisionCache(ReferenceType referenceType)
{
- this.referenceType = referenceType;
+ setReferenceType(referenceType);
}
public MEMRevisionCache()
@@ -67,6 +72,16 @@ public class MEMRevisionCache extends ReferenceQueueWorker<InternalCDORevision>
this(ReferenceType.SOFT);
}
+ public InternalCDORevisionCache instantiate(CDORevision revision)
+ {
+ return new MEMRevisionCache(referenceType);
+ }
+
+ public boolean isSupportingBranches()
+ {
+ return false;
+ }
+
public ReferenceType getReferenceType()
{
return referenceType;
@@ -74,6 +89,7 @@ public class MEMRevisionCache extends ReferenceQueueWorker<InternalCDORevision>
public void setReferenceType(ReferenceType referenceType)
{
+ checkInactive();
this.referenceType = referenceType;
}
@@ -82,41 +98,28 @@ public class MEMRevisionCache extends ReferenceQueueWorker<InternalCDORevision>
return null;
}
- public InternalCDORevision getRevision(CDOID id)
- {
- synchronized (cacheLists)
- {
- CacheList list = cacheLists.get(id);
- if (list != null)
- {
- return list.getRevision();
- }
- }
-
- return null;
- }
-
- public InternalCDORevision getRevisionByTime(CDOID id, long timeStamp)
+ public InternalCDORevision getRevision(CDOID id, CDOBranchPoint branchPoint)
{
synchronized (cacheLists)
{
CacheList list = cacheLists.get(id);
if (list != null)
{
- return list.getRevisionByTime(timeStamp);
+ return list.getRevision(branchPoint.getTimeStamp());
}
}
return null;
}
- public InternalCDORevision getRevisionByVersion(CDOID id, int version)
+ public InternalCDORevision getRevisionByVersion(CDOID id, CDOBranchVersion branchVersion)
{
synchronized (cacheLists)
{
CacheList list = cacheLists.get(id);
if (list != null)
{
+ int version = branchVersion.getVersion();
return list.getRevisionByVersion(version);
}
}
@@ -124,7 +127,7 @@ public class MEMRevisionCache extends ReferenceQueueWorker<InternalCDORevision>
return null;
}
- public List<CDORevision> getRevisions()
+ public List<CDORevision> getCurrentRevisions()
{
ArrayList<CDORevision> currentRevisions = new ArrayList<CDORevision>();
synchronized (cacheLists)
@@ -132,7 +135,7 @@ public class MEMRevisionCache extends ReferenceQueueWorker<InternalCDORevision>
for (Entry<CDOID, CacheList> entry : cacheLists.entrySet())
{
CacheList list = entry.getValue();
- InternalCDORevision revision = list.getRevision();
+ InternalCDORevision revision = list.getRevision(CDORevision.UNSPECIFIED_DATE);
if (revision != null)
{
currentRevisions.add(revision);
@@ -160,18 +163,14 @@ public class MEMRevisionCache extends ReferenceQueueWorker<InternalCDORevision>
}
}
- public void removeRevision(CDORevision revision)
- {
- removeRevision(revision.getID(), revision.getVersion());
- }
-
- public InternalCDORevision removeRevision(CDOID id, int version)
+ public InternalCDORevision removeRevision(CDOID id, CDOBranchVersion branchVersion)
{
synchronized (cacheLists)
{
CacheList list = cacheLists.get(id);
if (list != null)
{
+ int version = branchVersion.getVersion();
list.removeRevision(version);
if (list.isEmpty())
{
@@ -195,22 +194,28 @@ public class MEMRevisionCache extends ReferenceQueueWorker<InternalCDORevision>
}
}
+ public Map<CDOBranch, List<CDORevision>> getAllRevisions()
+ {
+ throw new UnsupportedOperationException();
+ }
+
@Override
@SuppressWarnings("unchecked")
protected void work(Reference<? extends InternalCDORevision> reference)
{
KeyedReference<CDOIDAndVersion, InternalCDORevision> keyedRef = (KeyedReference<CDOIDAndVersion, InternalCDORevision>)reference;
CDOIDAndVersion key = keyedRef.getKey();
- CDOID id = key.getID();
- int version = key.getVersion();
+ final CDOID id = key.getID();
+ final CDOBranch branch = null;
+ final int version = key.getVersion();
- InternalCDORevision revision = removeRevision(id, version);
+ InternalCDORevision revision = removeRevision(id, CDOBranchUtil.createBranchVersion(branch, version));
if (revision == null)
{
IListener[] listeners = getListeners();
if (listeners != null)
{
- fireEvent(new EvictionEventImpl(this, id, version), listeners);
+ fireEvent(new EvictionEventImpl(this, CDORevisionUtil.createRevisionKey(id, branch, version)), listeners);
}
}
else
@@ -259,22 +264,53 @@ public class MEMRevisionCache extends ReferenceQueueWorker<InternalCDORevision>
{
}
- public InternalCDORevision getRevision()
+ public InternalCDORevision getRevision(long timeStamp)
{
- KeyedReference<CDOIDAndVersion, InternalCDORevision> ref = isEmpty() ? null : getFirst();
- if (ref != null)
+ if (timeStamp == CDORevision.UNSPECIFIED_DATE)
+ {
+ KeyedReference<CDOIDAndVersion, InternalCDORevision> ref = isEmpty() ? null : getFirst();
+ if (ref != null)
+ {
+ InternalCDORevision revision = ref.get();
+ if (revision != null)
+ {
+ if (!revision.isHistorical())
+ {
+ return revision;
+ }
+ }
+ else
+ {
+ removeFirst();
+ }
+ }
+
+ return null;
+ }
+
+ for (Iterator<KeyedReference<CDOIDAndVersion, InternalCDORevision>> it = iterator(); it.hasNext();)
{
+ KeyedReference<CDOIDAndVersion, InternalCDORevision> ref = it.next();
InternalCDORevision revision = ref.get();
if (revision != null)
{
- if (revision.isCurrent())
+ long created = revision.getTimeStamp();
+ if (created <= timeStamp)
{
- return revision;
+ long revised = revision.getRevised();
+ if (timeStamp <= revised || revised == CDORevision.UNSPECIFIED_DATE)
+ {
+ return revision;
+ }
+ else
+ {
+ break;
+ }
}
}
else
{
- removeFirst();
+ it.remove();
}
}
@@ -308,11 +344,6 @@ public class MEMRevisionCache extends ReferenceQueueWorker<InternalCDORevision>
return null;
}
- public InternalCDORevision getRevisionByTime(long timeStamp)
- {
- return getRevisionByTime(timeStamp, false);
- }
-
public void removeRevision(int version)
{
for (Iterator<KeyedReference<CDOIDAndVersion, InternalCDORevision>> it = iterator(); it.hasNext();)
@@ -344,7 +375,8 @@ public class MEMRevisionCache extends ReferenceQueueWorker<InternalCDORevision>
for (ListIterator<KeyedReference<CDOIDAndVersion, InternalCDORevision>> it = listIterator(); it.hasNext();)
{
KeyedReference<CDOIDAndVersion, InternalCDORevision> ref = it.next();
- if (ref.get() != null)
+ InternalCDORevision foundRevision = ref.get();
+ if (foundRevision != null)
{
CDOIDAndVersion key = ref.getKey();
int v = key.getVersion();
@@ -369,41 +401,5 @@ public class MEMRevisionCache extends ReferenceQueueWorker<InternalCDORevision>
addLast(reference);
return true;
}
-
- private InternalCDORevision getRevisionByTime(long timeStamp, boolean onlyResource)
- {
- for (Iterator<KeyedReference<CDOIDAndVersion, InternalCDORevision>> it = iterator(); it.hasNext();)
- {
- KeyedReference<CDOIDAndVersion, InternalCDORevision> ref = it.next();
- InternalCDORevision revision = ref.get();
- if (revision != null)
- {
- if (onlyResource && !revision.isResource())
- {
- return null;
- }
-
- long created = revision.getCreated();
- if (created <= timeStamp)
- {
- long revised = revision.getRevised();
- if (timeStamp <= revised || revised == CDORevision.UNSPECIFIED_DATE)
- {
- return revision;
- }
- else
- {
- break;
- }
- }
- }
- else
- {
- it.remove();
- }
- }
-
- return null;
- }
}
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/noop/NOOPRevisionCache.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/noop/NOOPRevisionCache.java
index e2c38b0756..342b55253a 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/noop/NOOPRevisionCache.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/noop/NOOPRevisionCache.java
@@ -10,9 +10,12 @@
*/
package org.eclipse.emf.cdo.internal.common.revision.cache.noop;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCache;
+import org.eclipse.emf.cdo.common.revision.cache.InternalCDORevisionCache;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.net4j.util.CheckUtil;
@@ -22,11 +25,12 @@ import org.eclipse.emf.ecore.EClass;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
/**
* @author Eike Stepper
*/
-public class NOOPRevisionCache extends Lifecycle implements CDORevisionCache
+public class NOOPRevisionCache extends Lifecycle implements InternalCDORevisionCache
{
public static final NOOPRevisionCache INSTANCE = new NOOPRevisionCache();
@@ -36,12 +40,22 @@ public class NOOPRevisionCache extends Lifecycle implements CDORevisionCache
{
}
+ public InternalCDORevisionCache instantiate(CDORevision revision)
+ {
+ return this;
+ }
+
+ public boolean isSupportingBranches()
+ {
+ return true;
+ }
+
public EClass getObjectType(CDOID id)
{
return null;
}
- public List<CDORevision> getRevisions()
+ public List<CDORevision> getCurrentRevisions()
{
return EMPTY;
}
@@ -51,12 +65,12 @@ public class NOOPRevisionCache extends Lifecycle implements CDORevisionCache
return null;
}
- public InternalCDORevision getRevisionByTime(CDOID id, long timeStamp)
+ public InternalCDORevision getRevision(CDOID id, CDOBranchPoint branchPoint)
{
return null;
}
- public InternalCDORevision getRevisionByVersion(CDOID id, int version)
+ public InternalCDORevision getRevisionByVersion(CDOID id, CDOBranchVersion branchVersion)
{
return null;
}
@@ -67,11 +81,7 @@ public class NOOPRevisionCache extends Lifecycle implements CDORevisionCache
return false;
}
- public void removeRevision(CDORevision revision)
- {
- }
-
- public InternalCDORevision removeRevision(CDOID id, int version)
+ public InternalCDORevision removeRevision(CDOID id, CDOBranchVersion branchVersion)
{
return null;
}
@@ -80,4 +90,9 @@ public class NOOPRevisionCache extends Lifecycle implements CDORevisionCache
{
// Do nothing
}
+
+ public Map<CDOBranch, List<CDORevision>> getAllRevisions()
+ {
+ return Collections.emptyMap();
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/two/TwoLevelRevisionCache.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/two/TwoLevelRevisionCache.java
index aa39556701..d56c635e61 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/two/TwoLevelRevisionCache.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/cache/two/TwoLevelRevisionCache.java
@@ -12,9 +12,13 @@
*/
package org.eclipse.emf.cdo.internal.common.revision.cache.two;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCache;
+import org.eclipse.emf.cdo.common.revision.cache.InternalCDORevisionCache;
import org.eclipse.emf.cdo.internal.common.bundle.OM;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
@@ -29,38 +33,52 @@ import org.eclipse.emf.ecore.EClass;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
/**
* @author Eike Stepper
*/
-public class TwoLevelRevisionCache extends Lifecycle implements CDORevisionCache, IListener
+public class TwoLevelRevisionCache extends Lifecycle implements InternalCDORevisionCache, IListener
{
private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REVISION, TwoLevelRevisionCache.class);
- private CDORevisionCache level1;
+ private InternalCDORevisionCache level1;
- private CDORevisionCache level2;
+ private InternalCDORevisionCache level2;
public TwoLevelRevisionCache()
{
}
- public CDORevisionCache getLevel1()
+ public InternalCDORevisionCache instantiate(CDORevision revision)
+ {
+ TwoLevelRevisionCache cache = new TwoLevelRevisionCache();
+ cache.setLevel1(level1.instantiate(revision));
+ cache.setLevel2(level2.instantiate(revision));
+ return cache;
+ }
+
+ public boolean isSupportingBranches()
+ {
+ return false;
+ }
+
+ public InternalCDORevisionCache getLevel1()
{
return level1;
}
- public void setLevel1(CDORevisionCache level1)
+ public void setLevel1(InternalCDORevisionCache level1)
{
this.level1 = level1;
}
- public CDORevisionCache getLevel2()
+ public InternalCDORevisionCache getLevel2()
{
return level2;
}
- public void setLevel2(CDORevisionCache level2)
+ public void setLevel2(InternalCDORevisionCache level2)
{
this.level2 = level2;
}
@@ -76,44 +94,33 @@ public class TwoLevelRevisionCache extends Lifecycle implements CDORevisionCache
return objectType;
}
- public CDORevision getRevision(CDOID id)
+ public CDORevision getRevision(CDOID id, CDOBranchPoint branchPoint)
{
- CDORevision revision = level1.getRevision(id);
+ CDORevision revision = level1.getRevision(id, branchPoint);
if (revision == null)
{
- revision = level2.getRevision(id);
+ revision = level2.getRevision(id, branchPoint);
}
return revision;
}
- public CDORevision getRevisionByTime(CDOID id, long timeStamp)
+ public CDORevision getRevisionByVersion(CDOID id, CDOBranchVersion branchVersion)
{
- CDORevision revision = level1.getRevisionByTime(id, timeStamp);
+ CDORevision revision = level1.getRevisionByVersion(id, branchVersion);
if (revision == null)
{
- revision = level2.getRevisionByTime(id, timeStamp);
+ revision = level2.getRevisionByVersion(id, branchVersion);
}
return revision;
}
- public CDORevision getRevisionByVersion(CDOID id, int version)
- {
- CDORevision revision = level1.getRevisionByVersion(id, version);
- if (revision == null)
- {
- revision = level2.getRevisionByVersion(id, version);
- }
-
- return revision;
- }
-
- public List<CDORevision> getRevisions()
+ public List<CDORevision> getCurrentRevisions()
{
List<CDORevision> revisions = new ArrayList<CDORevision>();
- revisions.addAll(level1.getRevisions());
- revisions.addAll(level2.getRevisions());
+ revisions.addAll(level1.getCurrentRevisions());
+ revisions.addAll(level2.getCurrentRevisions());
return revisions;
}
@@ -124,20 +131,20 @@ public class TwoLevelRevisionCache extends Lifecycle implements CDORevisionCache
// Bugzilla 292372: If a new current revision was added to level1, we must check whether
// level2 contains a stale current revision, and revise that revision if possible
- if (added && revision.isCurrent())
+ if (added && !revision.isHistorical())
{
CDOID id = revision.getID();
- CDORevision revisionInLevel2 = level2.getRevision(id);
- if (revisionInLevel2 != null && revisionInLevel2.isCurrent())
+ CDORevision revisionInLevel2 = level2.getRevision(id, revision);
+ if (revisionInLevel2 != null && !revisionInLevel2.isHistorical())
{
// We can only revise if the revisions are consecutive
if (revision.getVersion() == revisionInLevel2.getVersion() + 1)
{
- ((InternalCDORevision)revisionInLevel2).setRevised(revision.getCreated() - 1);
+ ((InternalCDORevision)revisionInLevel2).setRevised(revision.getTimeStamp() - 1);
}
else
{
- level2.removeRevision(id, revisionInLevel2.getVersion());
+ level2.removeRevision(id, revision.getBranch().getVersion(revisionInLevel2.getVersion()));
}
}
}
@@ -145,20 +152,11 @@ public class TwoLevelRevisionCache extends Lifecycle implements CDORevisionCache
return added;
}
- public void removeRevision(CDORevision revision)
- {
- removeRevision(revision.getID(), revision.getVersion());
- }
-
- public CDORevision removeRevision(CDOID id, int version)
+ public CDORevision removeRevision(CDOID id, CDOBranchVersion branchVersion)
{
- CDORevision revision = level1.removeRevision(id, version);
- if (revision == null)
- {
- revision = level2.removeRevision(id, version);
- }
-
- return revision;
+ CDORevision revision1 = level1.removeRevision(id, branchVersion);
+ CDORevision revision2 = level2.removeRevision(id, branchVersion);
+ return revision1 != null ? revision1 : revision2;
}
public void clear()
@@ -167,6 +165,11 @@ public class TwoLevelRevisionCache extends Lifecycle implements CDORevisionCache
level2.clear();
}
+ public Map<CDOBranch, List<CDORevision>> getAllRevisions()
+ {
+ throw new UnsupportedOperationException();
+ }
+
public void notifyEvent(IEvent event)
{
if (event instanceof EvictionEvent)
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java
index 1fedcee224..7e7a9401f7 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java
@@ -12,6 +12,7 @@
*/
package org.eclipse.emf.cdo.internal.common.revision.delta;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.io.CDODataInput;
import org.eclipse.emf.cdo.common.io.CDODataOutput;
@@ -24,7 +25,6 @@ import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
import org.eclipse.emf.ecore.EClass;
@@ -42,30 +42,30 @@ import java.util.Map;
*/
public class CDORevisionDeltaImpl implements InternalCDORevisionDelta
{
- private CDOID cdoID;
-
private EClass eClass;
- private int dirtyVersion;
+ private CDOID id;
+
+ private CDOBranch branch;
- private int originVersion;
+ private int version;
private Map<EStructuralFeature, CDOFeatureDelta> featureDeltas = new HashMap<EStructuralFeature, CDOFeatureDelta>();
public CDORevisionDeltaImpl(CDORevision revision)
{
- cdoID = revision.getID();
eClass = revision.getEClass();
- dirtyVersion = revision.getVersion();
- originVersion = dirtyVersion - 1;
+ id = revision.getID();
+ branch = revision.getBranch();
+ version = revision.getVersion();
}
public CDORevisionDeltaImpl(CDORevisionDelta revisionDelta)
{
- cdoID = revisionDelta.getID();
- eClass = ((CDORevisionDeltaImpl)revisionDelta).eClass;
- dirtyVersion = revisionDelta.getDirtyVersion();
- originVersion = revisionDelta.getOriginVersion();
+ eClass = revisionDelta.getEClass();
+ id = revisionDelta.getID();
+ branch = revisionDelta.getBranch();
+ version = revisionDelta.getVersion();
for (CDOFeatureDelta delta : revisionDelta.getFeatureDeltas())
{
@@ -75,15 +75,18 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta
public CDORevisionDeltaImpl(CDORevision originRevision, CDORevision dirtyRevision)
{
- if (originRevision.getEClass() != dirtyRevision.getEClass())
+ if ( //
+ originRevision.getEClass() //
+ != //
+ dirtyRevision.getEClass())
{
throw new IllegalArgumentException();
}
- cdoID = originRevision.getID();
eClass = originRevision.getEClass();
- dirtyVersion = dirtyRevision.getVersion();
- originVersion = originRevision.getVersion();
+ id = originRevision.getID();
+ branch = originRevision.getBranch();
+ version = originRevision.getVersion();
compare(originRevision, dirtyRevision);
@@ -101,9 +104,9 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta
public CDORevisionDeltaImpl(CDODataInput in) throws IOException
{
eClass = (EClass)in.readCDOClassifierRefAndResolve();
- cdoID = in.readCDOID();
- originVersion = in.readInt();
- dirtyVersion = in.readInt();
+ id = in.readCDOID();
+ branch = in.readCDOBranch();
+ version = in.readInt();
int size = in.readInt();
for (int i = 0; i < size; i++)
{
@@ -115,9 +118,9 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta
public void write(CDODataOutput out) throws IOException
{
out.writeCDOClassifierRef(eClass);
- out.writeCDOID(cdoID);
- out.writeInt(originVersion);
- out.writeInt(dirtyVersion);
+ out.writeCDOID(id);
+ out.writeCDOBranch(branch);
+ out.writeInt(version);
out.writeInt(featureDeltas.size());
for (CDOFeatureDelta featureDelta : featureDeltas.values())
{
@@ -125,34 +128,34 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta
}
}
- public CDOID getID()
+ public EClass getEClass()
{
- return cdoID;
+ return eClass;
}
- public EClass getEClass()
+ public CDOID getID()
{
- return eClass;
+ return id;
}
- public int getOriginVersion()
+ public CDOBranch getBranch()
{
- return originVersion;
+ return branch;
}
- public void setOriginVersion(int originVersion)
+ public void setBranch(CDOBranch branch)
{
- this.originVersion = originVersion;
+ this.branch = branch;
}
- public int getDirtyVersion()
+ public int getVersion()
{
- return dirtyVersion;
+ return version;
}
- public void setDirtyVersion(int dirtyVersion)
+ public void setVersion(int version)
{
- this.dirtyVersion = dirtyVersion;
+ this.version = version;
}
public List<CDOFeatureDelta> getFeatureDeltas()
@@ -162,7 +165,8 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta
public void apply(CDORevision revision)
{
- ((InternalCDORevision)revision).setVersion(dirtyVersion);
+ // ((InternalCDORevision)revision).setBranchPoint(branch.getPoint(revision.getTimeStamp()));
+ // ((InternalCDORevision)revision).setVersion(version);
for (CDOFeatureDelta featureDelta : featureDeltas.values())
{
((CDOFeatureDeltaImpl)featureDelta).apply(revision);
@@ -307,7 +311,6 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta
@Override
public String toString()
{
- return MessageFormat.format("CDORevisionDelta[{0}@{1}v{2} -> v{3}]", eClass.getName(), cdoID, originVersion,
- dirtyVersion);
+ return MessageFormat.format("CDORevisionDelta[{0}@{1}:{2}v{3}]", eClass.getName(), id, branch.getID(), version);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/branch/CDOBranchUtil.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/branch/CDOBranchUtil.java
new file mode 100644
index 0000000000..8f1abf0b1a
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/branch/CDOBranchUtil.java
@@ -0,0 +1,54 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.spi.common.branch;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.internal.common.branch.CDOBranchManagerImpl;
+import org.eclipse.emf.cdo.internal.common.branch.CDOBranchPointImpl;
+import org.eclipse.emf.cdo.internal.common.branch.CDOBranchVersionImpl;
+
+/**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+public final class CDOBranchUtil
+{
+ private CDOBranchUtil()
+ {
+ }
+
+ public static InternalCDOBranchManager createBranchManager()
+ {
+ return new CDOBranchManagerImpl();
+ }
+
+ public static CDOBranchPoint createBranchPoint(CDOBranch branch, long timeStamp)
+ {
+ return new CDOBranchPointImpl(branch, timeStamp);
+ }
+
+ public static CDOBranchPoint createBranchPoint(CDOBranchPoint source)
+ {
+ return createBranchPoint(source.getBranch(), source.getTimeStamp());
+ }
+
+ public static CDOBranchVersion createBranchVersion(CDOBranch branch, int version)
+ {
+ return new CDOBranchVersionImpl(branch, version);
+ }
+
+ public static CDOBranchVersion createBranchVersion(CDOBranchVersion source)
+ {
+ return createBranchVersion(source.getBranch(), source.getVersion());
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/branch/InternalCDOBranch.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/branch/InternalCDOBranch.java
new file mode 100644
index 0000000000..5065cee5f9
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/branch/InternalCDOBranch.java
@@ -0,0 +1,39 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.spi.common.branch;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager.BranchLoader.BranchInfo;
+
+/**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+public interface InternalCDOBranch extends CDOBranch
+{
+ public boolean isProxy();
+
+ public InternalCDOBranchManager getBranchManager();
+
+ public InternalCDOBranch[] getBranches();
+
+ public InternalCDOBranch getBranch(String path);
+
+ public InternalCDOBranch createBranch(String name, long timeStamp);
+
+ public InternalCDOBranch createBranch(String name);
+
+ public BranchInfo getBranchInfo();
+
+ public void setBranchInfo(String name, InternalCDOBranch baseBranch, long baseTimeStamp);
+
+ public void addChild(InternalCDOBranch branch);
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/branch/InternalCDOBranchManager.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/branch/InternalCDOBranchManager.java
new file mode 100644
index 0000000000..ccc6737d29
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/branch/InternalCDOBranchManager.java
@@ -0,0 +1,160 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.spi.common.branch;
+
+import org.eclipse.emf.cdo.common.CDOTimeProvider;
+import org.eclipse.emf.cdo.common.branch.CDOBranchManager;
+import org.eclipse.emf.cdo.common.io.CDODataInput;
+import org.eclipse.emf.cdo.common.io.CDODataOutput;
+
+import org.eclipse.net4j.util.lifecycle.ILifecycle;
+
+import java.io.IOException;
+
+/**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+public interface InternalCDOBranchManager extends CDOBranchManager, ILifecycle
+{
+ public BranchLoader getBranchLoader();
+
+ public void setBranchLoader(BranchLoader branchLoader);
+
+ public CDOTimeProvider getTimeProvider();
+
+ public void setTimeProvider(CDOTimeProvider timeProvider);
+
+ public void initMainBranch(long timestamp);
+
+ public InternalCDOBranch getMainBranch();
+
+ public InternalCDOBranch getBranch(int branchID);
+
+ public InternalCDOBranch getBranch(int id, String name, long baseTimeStamp, InternalCDOBranch base);
+
+ public InternalCDOBranch getBranch(String path);
+
+ public InternalCDOBranch createBranch(String name, InternalCDOBranch baseBranch, long baseTimeStamp);
+
+ public void handleBranchCreated(InternalCDOBranch branch);
+
+ /**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+ public interface BranchLoader
+ {
+ public int createBranch(BranchInfo branchInfo);
+
+ public BranchInfo loadBranch(int branchID);
+
+ public SubBranchInfo[] loadSubBranches(int branchID);
+
+ /**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+ public static final class BranchInfo
+ {
+ private String name;
+
+ private int baseBranchID;
+
+ private long baseTimeStamp;
+
+ public BranchInfo(String name, int baseBranchID, long baseTimeStamp)
+ {
+ this.name = name;
+ this.baseBranchID = baseBranchID;
+ this.baseTimeStamp = baseTimeStamp;
+ }
+
+ public BranchInfo(CDODataInput in) throws IOException
+ {
+ name = in.readString();
+ baseBranchID = in.readInt();
+ baseTimeStamp = in.readLong();
+ }
+
+ public void write(CDODataOutput out) throws IOException
+ {
+ out.writeString(name);
+ out.writeInt(baseBranchID);
+ out.writeLong(baseTimeStamp);
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public int getBaseBranchID()
+ {
+ return baseBranchID;
+ }
+
+ public long getBaseTimeStamp()
+ {
+ return baseTimeStamp;
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+ public static final class SubBranchInfo
+ {
+ private int id;
+
+ private String name;
+
+ private long baseTimeStamp;
+
+ public SubBranchInfo(int id, String name, long baseTimeStamp)
+ {
+ this.id = id;
+ this.name = name;
+ this.baseTimeStamp = baseTimeStamp;
+ }
+
+ public SubBranchInfo(CDODataInput in) throws IOException
+ {
+ id = in.readInt();
+ name = in.readString();
+ baseTimeStamp = in.readLong();
+ }
+
+ public void write(CDODataOutput out) throws IOException
+ {
+ out.writeInt(id);
+ out.writeString(name);
+ out.writeLong(baseTimeStamp);
+ }
+
+ public int getID()
+ {
+ return id;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public long getBaseTimeStamp()
+ {
+ return baseTimeStamp;
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/AbstractCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/AbstractCDORevision.java
index 3aaf9605eb..9741d7e02d 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/AbstractCDORevision.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/AbstractCDORevision.java
@@ -13,41 +13,12 @@
*/
package org.eclipse.emf.cdo.spi.common.revision;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOIDProvider;
-import org.eclipse.emf.cdo.common.id.CDOIDTemp;
-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.branch.CDOBranch;
import org.eclipse.emf.cdo.common.model.CDOClassInfo;
-import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
-import org.eclipse.emf.cdo.common.model.CDOModelUtil;
-import org.eclipse.emf.cdo.common.model.CDOType;
-import org.eclipse.emf.cdo.common.revision.CDOList;
-import org.eclipse.emf.cdo.common.revision.CDOListFactory;
-import org.eclipse.emf.cdo.common.revision.CDOReferenceAdjuster;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionData;
-import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDeltaUtil;
-import org.eclipse.emf.cdo.internal.common.bundle.OM;
-import org.eclipse.emf.cdo.internal.common.messages.Messages;
-
-import org.eclipse.net4j.util.om.trace.ContextTracer;
-import org.eclipse.net4j.util.om.trace.PerfTracer;
import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EClassifier;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.InternalEObject.EStore;
-import org.eclipse.emf.ecore.util.FeatureMap;
-import org.eclipse.emf.ecore.util.FeatureMapUtil;
-import org.eclipse.emf.ecore.util.FeatureMap.Entry;
-
-import java.io.IOException;
-import java.text.MessageFormat;
-import java.util.Map;
/**
* @author Eike Stepper
@@ -55,323 +26,30 @@ import java.util.Map;
*/
public abstract class AbstractCDORevision implements InternalCDORevision
{
- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REVISION, AbstractCDORevision.class);
-
- private static final PerfTracer READING = new PerfTracer(OM.PERF_REVISION_READING, AbstractCDORevision.class);
-
- private static final PerfTracer WRITING = new PerfTracer(OM.PERF_REVISION_WRITING, AbstractCDORevision.class);
-
- private static final byte UNSET = 0;
-
- private static final byte SET_NULL = 1;
-
- private static final byte SET_NOT_NULL = 2;
-
- private CDOClassInfo classInfo;
-
- private CDOID id;
-
- private int version;
-
- private long created;
-
- private long revised;
-
- private CDOID resourceID;
-
- private Object containerID;
-
- private int containingFeatureID;
-
- /**
- * @since 3.0
- */
- public AbstractCDORevision(EClass eClass)
- {
- if (eClass != null)
- {
- if (eClass.isAbstract())
- {
- throw new IllegalArgumentException(MessageFormat.format(Messages.getString("AbstractCDORevision.0"), eClass)); //$NON-NLS-1$
- }
-
- classInfo = CDOModelUtil.getClassInfo(eClass);
- version = 0;
- created = UNSPECIFIED_DATE;
- revised = UNSPECIFIED_DATE;
- resourceID = CDOID.NULL;
- containerID = CDOID.NULL;
- containingFeatureID = 0;
- initValues(classInfo.getAllPersistentFeatures());
- }
- }
-
- protected AbstractCDORevision(AbstractCDORevision source)
- {
- classInfo = source.classInfo;
- id = source.id;
- version = source.version;
- created = source.created;
- revised = source.revised; // == UNSPECIFIED
- resourceID = source.resourceID;
- containerID = source.containerID;
- containingFeatureID = source.containingFeatureID;
- }
-
- /**
- * @since 3.0
- */
- public void read(CDODataInput in) throws IOException
- {
- READING.start(this);
- EClassifier classifier = in.readCDOClassifierRefAndResolve();
- classInfo = CDOModelUtil.getClassInfo((EClass)classifier);
-
- id = in.readCDOID();
- version = in.readInt();
- if (!id.isTemporary())
- {
- created = in.readLong();
- revised = in.readLong();
- }
-
- resourceID = in.readCDOID();
- containerID = in.readCDOID();
- containingFeatureID = in.readInt();
- if (TRACER.isEnabled())
- {
- TRACER
- .format(
- "Reading revision: ID={0}, className={1}, version={2}, created={3}, revised={4}, resource={5}, container={6}, featureID={7}", //$NON-NLS-1$
- id, getEClass().getName(), version, created, revised, resourceID, containerID, containingFeatureID);
- }
-
- readValues(in);
- READING.stop(this);
- }
-
- public void write(CDODataOutput out, int referenceChunk) throws IOException
- {
- EClass eClass = getEClass();
- CDOClassifierRef classRef = new CDOClassifierRef(eClass);
- if (TRACER.isEnabled())
- {
- TRACER
- .format(
- "Writing revision: ID={0}, className={1}, version={2}, created={3}, revised={4}, resource={5}, container={6}, featureID={7}", //$NON-NLS-1$
- id, eClass.getName(), getVersion(), created, revised, resourceID, containerID, containingFeatureID);
- }
-
- WRITING.start(this);
-
- out.writeCDOClassifierRef(classRef);
- out.writeCDOID(id);
- out.writeInt(getVersion());
- if (!id.isTemporary())
- {
- out.writeLong(created);
- out.writeLong(revised);
- }
-
- out.writeCDOID(resourceID);
- out.writeCDOID(out.getIDProvider().provideCDOID(containerID));
- out.writeInt(containingFeatureID);
- writeValues(out, referenceChunk);
- WRITING.stop(this);
- }
-
- /**
- * @see #write(CDODataOutput, int)
- * @since 3.0
- */
- public void convertEObjects(CDOIDProvider idProvider)
- {
- if (!(containerID instanceof CDOID))
- {
- containerID = idProvider.provideCDOID(containerID);
- }
-
- EStructuralFeature[] features = classInfo.getAllPersistentFeatures();
- for (int i = 0; i < features.length; i++)
- {
- EStructuralFeature feature = features[i];
- if (feature.isMany())
- {
- CDOList list = getValueAsList(i);
- if (list != null)
- {
- boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature);
- for (int j = 0; j < list.size(); j++)
- {
- Object value = list.get(j, false);
- EStructuralFeature innerFeature = feature; // Prepare for possible feature map
- if (isFeatureMap)
- {
- Entry entry = (FeatureMap.Entry)value;
- innerFeature = entry.getEStructuralFeature();
- value = entry.getValue();
- }
-
- if (value != null && innerFeature instanceof EReference)
- {
- CDOID newValue = idProvider.provideCDOID(value);
- if (newValue != value)
- {
- list.set(j, newValue);
- }
- }
- }
- }
- }
- else
- {
- checkNoFeatureMap(feature);
- Object value = getValue(i);
- if (value != null && feature instanceof EReference)
- {
- CDOID newValue = idProvider.provideCDOID(value);
- if (newValue != value)
- {
- setValue(i, newValue);
- }
- }
- }
- }
- }
-
- /**
- * @since 3.0
- */
- public CDOClassInfo getClassInfo()
- {
- return classInfo;
- }
-
public EClass getEClass()
{
- return classInfo.getEClass();
- }
-
- public CDOID getID()
- {
- return id;
- }
-
- public void setID(CDOID id)
- {
- if (CDOIDUtil.isNull(id))
- {
- throw new IllegalArgumentException(Messages.getString("AbstractCDORevision.1")); //$NON-NLS-1$
- }
-
- if (TRACER.isEnabled())
- {
- TRACER.format("Setting ID: {0}", id);
- }
-
- this.id = id;
- }
-
- public int getVersion()
- {
- return version < 0 ? -version : version;
- }
-
- public void setVersion(int version)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Setting version for {0}: v{1}", this, version);
- }
-
- this.version = version;
- }
-
- public boolean isTransactional()
- {
- return version < 0;
- }
-
- /**
- * @since 3.0
- */
- public int setTransactional(boolean on)
- {
- if (on)
- {
- version = -(version + 1);
- }
- else
+ CDOClassInfo classInfo = getClassInfo();
+ if (classInfo != null)
{
- version = Math.abs(version);
+ return classInfo.getEClass();
}
- if (TRACER.isEnabled())
- {
- TRACER.format("Setting transactional={0} for {1}", on, this);
- }
-
- return version;
- }
-
- public long getCreated()
- {
- return created;
- }
-
- public void setCreated(long created)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Setting created {0}: {1,date} {1,time}", this, created);
- }
-
- this.created = created;
- }
-
- public long getRevised()
- {
- return revised;
- }
-
- public void setRevised(long revised)
- {
- if (revised != UNSPECIFIED_DATE && revised < Math.max(0, created))
- {
- throw new IllegalArgumentException("created=" + created + ", revised=" + revised);
- }
-
- if (TRACER.isEnabled())
- {
- TRACER.format("Setting revised {0}: {1,date} {1,time}", this, revised);
- }
-
- this.revised = revised;
- }
-
- public boolean isCurrent()
- {
- return revised == UNSPECIFIED_DATE;
- }
-
- public boolean isValid(long timeStamp)
- {
- return (revised == UNSPECIFIED_DATE || revised >= timeStamp) && timeStamp >= created;
+ return null;
}
public boolean isResourceNode()
{
- return classInfo.isResourceNode();
+ return getClassInfo().isResourceNode();
}
public boolean isResourceFolder()
{
- return classInfo.isResourceFolder();
+ return getClassInfo().isResourceFolder();
}
public boolean isResource()
{
- return classInfo.isResource();
+ return getClassInfo().isResource();
}
public CDORevisionData data()
@@ -384,369 +62,52 @@ public abstract class AbstractCDORevision implements InternalCDORevision
return this;
}
- public InternalCDORevisionDelta compare(CDORevision origin)
- {
- return (InternalCDORevisionDelta)CDORevisionDeltaUtil.create(origin, this);
- }
-
- public void merge(CDORevisionDelta delta)
- {
- CDORevisionMerger applier = new CDORevisionMerger();
- applier.merge(this, delta);
- }
-
- public CDOID getResourceID()
- {
- return resourceID;
- }
-
- public void setResourceID(CDOID resourceID)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Setting resourceID {0}: {1}", this, resourceID);
- }
-
- this.resourceID = resourceID;
- }
-
- public Object getContainerID()
- {
- return containerID;
- }
-
- public void setContainerID(Object containerID)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Setting containerID {0}: {1}", this, containerID);
- }
-
- this.containerID = containerID;
- }
-
- public int getContainingFeatureID()
- {
- return containingFeatureID;
- }
-
- public void setContainingFeatureID(int containingFeatureID)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Setting containingFeatureID {0}: {1}", this, containingFeatureID);
- }
-
- this.containingFeatureID = containingFeatureID;
- }
-
- public int hashCode(EStructuralFeature feature)
- {
- return getValue(feature).hashCode();
- }
-
- public Object get(EStructuralFeature feature, int index)
- {
- if (feature.isMany() && index != EStore.NO_INDEX)
- {
- return getList(feature).get(index);
- }
-
- return getValue(feature);
- }
-
- public boolean contains(EStructuralFeature feature, Object value)
- {
- return getList(feature).contains(value);
- }
-
- public int indexOf(EStructuralFeature feature, Object value)
- {
- return getList(feature).indexOf(value);
- }
-
- public boolean isEmpty(EStructuralFeature feature)
- {
- return getList(feature).isEmpty();
- }
-
- public int lastIndexOf(EStructuralFeature feature, Object value)
- {
- return getList(feature).lastIndexOf(value);
- }
-
- public int size(EStructuralFeature feature)
- {
- return getList(feature).size();
- }
-
- public Object[] toArray(EStructuralFeature feature)
- {
- if (!feature.isMany())
- {
- throw new IllegalStateException("!feature.isMany()");
- }
-
- return getList(feature).toArray();
- }
-
- public <T> T[] toArray(EStructuralFeature feature, T[] array)
- {
- if (!feature.isMany())
- {
- throw new IllegalStateException("!feature.isMany()");
- }
-
- return getList(feature).toArray(array);
- }
-
- public void add(EStructuralFeature feature, int index, Object value)
- {
- getList(feature).add(index, value);
- }
-
- public void clear(EStructuralFeature feature)
- {
- setValue(feature, null);
- }
-
- public Object move(EStructuralFeature feature, int targetIndex, int sourceIndex)
+ /**
+ * @since 3.0
+ */
+ public boolean isHistorical()
{
- return getList(feature).move(targetIndex, sourceIndex);
+ return getRevised() != UNSPECIFIED_DATE;
}
- public Object remove(EStructuralFeature feature, int index)
+ public boolean isValid(long timeStamp)
{
- return getList(feature).remove(index);
+ long revised = getRevised();
+ return (revised == UNSPECIFIED_DATE || revised >= timeStamp) && timeStamp >= getTimeStamp();
}
- public Object set(EStructuralFeature feature, int index, Object value)
+ /**
+ * @since 3.0
+ */
+ public void adjustForCommit(CDOBranch branch, long timeStamp)
{
- if (feature.isMany())
+ if (branch.equals(getBranch()))
{
- return getList(feature).set(index, value);
+ // Same branch, increase version
+ setVersion(getVersion() + 1);
}
-
- return setValue(feature, value);
- }
-
- public void unset(EStructuralFeature feature)
- {
- setValue(feature, null);
- }
-
- public void adjustReferences(CDOReferenceAdjuster revisionAdjuster)
- {
- if (TRACER.isEnabled())
+ else
{
- TRACER.format("Adjusting references for revision {0}", this);
+ // Different branch, start with v1
+ setVersion(FIRST_VERSION);
}
- resourceID = (CDOID)revisionAdjuster.adjustReference(resourceID);
- containerID = revisionAdjuster.adjustReference(containerID);
-
- EStructuralFeature[] features = classInfo.getAllPersistentFeatures();
- for (int i = 0; i < features.length; i++)
- {
- EStructuralFeature feature = features[i];
- if (feature instanceof EReference || FeatureMapUtil.isFeatureMap(feature))
- {
- if (feature.isMany())
- {
- InternalCDOList list = (InternalCDOList)getValueAsList(i);
- if (list != null)
- {
- list.adjustReferences(revisionAdjuster, feature);
- }
- }
- else
- {
- CDOType type = CDOModelUtil.getType(feature);
- setValue(i, type.adjustReferences(revisionAdjuster, getValue(i)));
- }
- }
- }
+ setBranchPoint(branch.getPoint(timeStamp));
+ setRevised(UNSPECIFIED_DATE);
}
@Override
public String toString()
{
- return getEClass().getName() + "@" + id + "v" + version;
- }
-
- public Object getValue(EStructuralFeature feature)
- {
- int featureIndex = classInfo.getFeatureIndex(feature);
- return getValue(featureIndex);
- }
-
- public Object setValue(EStructuralFeature feature, Object value)
- {
- int featureIndex = classInfo.getFeatureIndex(feature);
-
- try
- {
- Object old = getValue(featureIndex);
- setValue(featureIndex, value);
- return old;
- }
- catch (ArrayIndexOutOfBoundsException ex)
- {
- throw new IllegalArgumentException(MessageFormat.format(Messages.getString("AbstractCDORevision.20"), feature,
- classInfo), ex);
- }
- }
-
- public CDOList getList(EStructuralFeature feature)
- {
- return getList(feature, 0);
- }
-
- public CDOList getList(EStructuralFeature feature, int size)
- {
- int featureIndex = classInfo.getFeatureIndex(feature);
- CDOList list = (CDOList)getValue(featureIndex);
- if (list == null && size != -1)
- {
- list = CDOListFactory.DEFAULT.createList(size, 0, 0);
- setValue(featureIndex, list);
- }
-
- return list;
- }
-
- public void setList(EStructuralFeature feature, InternalCDOList list)
- {
- int featureIndex = classInfo.getFeatureIndex(feature);
- setValue(featureIndex, list);
- }
-
- protected abstract void initValues(EStructuralFeature[] allPersistentFeatures);
-
- protected abstract Object getValue(int featureIndex);
-
- protected abstract void setValue(int featureIndex, Object value);
-
- private CDOList getValueAsList(int i)
- {
- return (CDOList)getValue(i);
- }
-
- private void writeValues(CDODataOutput out, int referenceChunk) throws IOException
- {
- EClass owner = getEClass();
- EStructuralFeature[] features = classInfo.getAllPersistentFeatures();
- for (int i = 0; i < features.length; i++)
- {
- EStructuralFeature feature = features[i];
- Object value = getValue(i);
- if (value == null)
- {
- // Feature is NOT set
- out.writeByte(UNSET);
- continue;
- }
-
- // Feature IS set
- if (value == CDORevisionData.NIL)
- {
- // Feature IS null
- out.writeByte(SET_NULL);
- continue;
- }
-
- // Feature is NOT null
- out.writeByte(SET_NOT_NULL);
- if (feature.isMany())
- {
- CDOList list = (CDOList)value;
- out.writeCDOList(owner, feature, list, referenceChunk);
- }
- else
- {
- checkNoFeatureMap(feature);
- if (value != null && feature instanceof EReference)
- {
- value = out.getIDProvider().provideCDOID(value);
- }
-
- if (TRACER.isEnabled())
- {
- TRACER.format("Writing feature {0}: {1}", feature.getName(), value);
- }
-
- out.writeCDOFeatureValue(feature, value);
- }
- }
- }
-
- private void readValues(CDODataInput in) throws IOException
- {
- EClass owner = getEClass();
- EStructuralFeature[] features = classInfo.getAllPersistentFeatures();
- initValues(features);
- for (int i = 0; i < features.length; i++)
- {
- Object value;
- EStructuralFeature feature = features[i];
- byte unsetState = in.readByte();
- switch (unsetState)
- {
- case UNSET:
- continue;
-
- case SET_NULL:
- setValue(i, CDORevisionData.NIL);
- continue;
- }
-
- if (feature.isMany())
- {
- value = in.readCDOList(owner, feature);
- }
- else
- {
- value = in.readCDOFeatureValue(feature);
- if (TRACER.isEnabled())
- {
- TRACER.format("Read feature {0}: {1}", feature.getName(), value);
- }
- }
-
- setValue(i, value);
- }
- }
-
- public static void checkNoFeatureMap(EStructuralFeature feature)
- {
- if (FeatureMapUtil.isFeatureMap(feature))
- {
- throw new UnsupportedOperationException("Single-valued feature maps not yet handled");
- }
- }
+ EClass eClass = getEClass();
+ String name = eClass == null ? "Revision" : eClass.getName();
- public static Object remapID(Object value, Map<CDOIDTemp, CDOID> idMappings)
- {
- if (value instanceof CDOIDTemp)
+ CDOBranch branch = getBranch();
+ if (branch == null)
{
- CDOIDTemp oldID = (CDOIDTemp)value;
- if (!oldID.isNull())
- {
- CDOID newID = idMappings.get(oldID);
- if (newID == null)
- {
- throw new IllegalStateException(MessageFormat.format(Messages.getString("AbstractCDORevision.2"), oldID));
- }
-
- if (TRACER.isEnabled())
- {
- TRACER.format("Adjusting ID: {0} --> {1}", oldID, newID);
- }
-
- return newID;
- }
+ return name + "@" + getID() + "v" + getVersion();
}
- return value;
+ return name + "@" + getID() + ":" + branch.getID() + "v" + getVersion();
}
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java
new file mode 100644
index 0000000000..5b4849836e
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java
@@ -0,0 +1,712 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ * Simon McDuff - bug 201266
+ * Simon McDuff - bug 212958
+ * Simon McDuff - bug 213402
+ */
+package org.eclipse.emf.cdo.spi.common.revision;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDProvider;
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+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.CDOClassInfo;
+import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
+import org.eclipse.emf.cdo.common.model.CDOModelUtil;
+import org.eclipse.emf.cdo.common.model.CDOType;
+import org.eclipse.emf.cdo.common.revision.CDOList;
+import org.eclipse.emf.cdo.common.revision.CDOListFactory;
+import org.eclipse.emf.cdo.common.revision.CDOReferenceAdjuster;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionData;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDeltaUtil;
+import org.eclipse.emf.cdo.internal.common.bundle.OM;
+import org.eclipse.emf.cdo.internal.common.messages.Messages;
+import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
+
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+import org.eclipse.net4j.util.om.trace.PerfTracer;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject.EStore;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.ecore.util.FeatureMapUtil;
+import org.eclipse.emf.ecore.util.FeatureMap.Entry;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.Map;
+
+/**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+public abstract class BaseCDORevision extends AbstractCDORevision
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REVISION, BaseCDORevision.class);
+
+ private static final PerfTracer READING = new PerfTracer(OM.PERF_REVISION_READING, BaseCDORevision.class);
+
+ private static final PerfTracer WRITING = new PerfTracer(OM.PERF_REVISION_WRITING, BaseCDORevision.class);
+
+ private static final byte UNSET = 0;
+
+ private static final byte SET_NULL = 1;
+
+ private static final byte SET_NOT_NULL = 2;
+
+ private CDOClassInfo classInfo;
+
+ private CDOID id;
+
+ private CDOBranchPoint branchPoint;
+
+ private int version;
+
+ private long revised;
+
+ private CDOID resourceID;
+
+ private Object containerID;
+
+ private int containingFeatureID;
+
+ /**
+ * @since 3.0
+ */
+ public BaseCDORevision(EClass eClass)
+ {
+ if (eClass != null)
+ {
+ if (eClass.isAbstract())
+ {
+ throw new IllegalArgumentException(MessageFormat.format(Messages.getString("AbstractCDORevision.0"), eClass)); //$NON-NLS-1$
+ }
+
+ classInfo = CDOModelUtil.getClassInfo(eClass);
+ version = UNSPECIFIED_VERSION;
+ revised = UNSPECIFIED_DATE;
+ resourceID = CDOID.NULL;
+ containerID = CDOID.NULL;
+ containingFeatureID = 0;
+ initValues(classInfo.getAllPersistentFeatures());
+ }
+ }
+
+ protected BaseCDORevision(BaseCDORevision source)
+ {
+ classInfo = source.classInfo;
+ id = source.id;
+ branchPoint = source.branchPoint;
+ version = source.version;
+ revised = source.revised; // == UNSPECIFIED_DATE
+ resourceID = source.resourceID;
+ containerID = source.containerID;
+ containingFeatureID = source.containingFeatureID;
+ }
+
+ /**
+ * @since 3.0
+ */
+ public void read(CDODataInput in) throws IOException
+ {
+ READING.start(this);
+ EClassifier classifier = in.readCDOClassifierRefAndResolve();
+ classInfo = CDOModelUtil.getClassInfo((EClass)classifier);
+
+ id = in.readCDOID();
+ branchPoint = in.readCDOBranchPoint();
+ version = in.readInt();
+ if (!id.isTemporary())
+ {
+ revised = in.readLong();
+ }
+
+ resourceID = in.readCDOID();
+ containerID = in.readCDOID();
+ containingFeatureID = in.readInt();
+ if (TRACER.isEnabled())
+ {
+ TRACER
+ .format(
+ "Reading revision: ID={0}, className={1}, version={2}, branchPoint={3}, revised={4}, resource={5}, container={6}, featureID={7}", //$NON-NLS-1$
+ id, getEClass().getName(), version, branchPoint, revised, resourceID, containerID, containingFeatureID);
+ }
+
+ readValues(in);
+ READING.stop(this);
+ }
+
+ public void write(CDODataOutput out, int referenceChunk) throws IOException
+ {
+ EClass eClass = getEClass();
+ CDOClassifierRef classRef = new CDOClassifierRef(eClass);
+ if (TRACER.isEnabled())
+ {
+ TRACER
+ .format(
+ "Writing revision: ID={0}, className={1}, version={2}, branchPoint={3}, revised={4}, resource={5}, container={6}, featureID={7}", //$NON-NLS-1$
+ id, eClass.getName(), getVersion(), branchPoint, revised, resourceID, containerID, containingFeatureID);
+ }
+
+ WRITING.start(this);
+
+ out.writeCDOClassifierRef(classRef);
+ out.writeCDOID(id);
+ out.writeCDOBranchPoint(branchPoint);
+ out.writeInt(getVersion());
+ if (!id.isTemporary())
+ {
+ out.writeLong(revised);
+ }
+
+ out.writeCDOID(resourceID);
+ out.writeCDOID(out.getIDProvider().provideCDOID(containerID));
+ out.writeInt(containingFeatureID);
+ writeValues(out, referenceChunk);
+ WRITING.stop(this);
+ }
+
+ /**
+ * @see #write(CDODataOutput, int)
+ * @since 3.0
+ */
+ public void convertEObjects(CDOIDProvider idProvider)
+ {
+ if (!(containerID instanceof CDOID))
+ {
+ containerID = idProvider.provideCDOID(containerID);
+ }
+
+ EStructuralFeature[] features = classInfo.getAllPersistentFeatures();
+ for (int i = 0; i < features.length; i++)
+ {
+ EStructuralFeature feature = features[i];
+ if (feature.isMany())
+ {
+ CDOList list = getValueAsList(i);
+ if (list != null)
+ {
+ boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature);
+ for (int j = 0; j < list.size(); j++)
+ {
+ Object value = list.get(j, false);
+ EStructuralFeature innerFeature = feature; // Prepare for possible feature map
+ if (isFeatureMap)
+ {
+ Entry entry = (FeatureMap.Entry)value;
+ innerFeature = entry.getEStructuralFeature();
+ value = entry.getValue();
+ }
+
+ if (value != null && innerFeature instanceof EReference)
+ {
+ CDOID newValue = idProvider.provideCDOID(value);
+ if (newValue != value)
+ {
+ list.set(j, newValue);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ checkNoFeatureMap(feature);
+ Object value = getValue(i);
+ if (value != null && feature instanceof EReference)
+ {
+ CDOID newValue = idProvider.provideCDOID(value);
+ if (newValue != value)
+ {
+ setValue(i, newValue);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @since 3.0
+ */
+ public CDOClassInfo getClassInfo()
+ {
+ return classInfo;
+ }
+
+ public CDOID getID()
+ {
+ return id;
+ }
+
+ public void setID(CDOID id)
+ {
+ if (CDOIDUtil.isNull(id))
+ {
+ throw new IllegalArgumentException(Messages.getString("AbstractCDORevision.1")); //$NON-NLS-1$
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting ID: {0}", id);
+ }
+
+ this.id = id;
+ }
+
+ /**
+ * @since 3.0
+ */
+ public CDOBranch getBranch()
+ {
+ if (branchPoint == null)
+ {
+ return null;
+ }
+
+ return branchPoint.getBranch();
+ }
+
+ /**
+ * @since 3.0
+ */
+ public long getTimeStamp()
+ {
+ if (branchPoint == null)
+ {
+ return UNSPECIFIED_DATE;
+ }
+
+ return branchPoint.getTimeStamp();
+ }
+
+ /**
+ * @since 3.0
+ */
+ public void setBranchPoint(CDOBranchPoint branchPoint)
+ {
+ branchPoint = CDOBranchUtil.createBranchPoint(branchPoint);
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting branchPoint {0}: {1}", this, branchPoint);
+ }
+
+ this.branchPoint = branchPoint;
+ }
+
+ public int getVersion()
+ {
+ return version;
+ }
+
+ public void setVersion(int version)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting version for {0}: v{1}", this, version);
+ }
+
+ this.version = version;
+ }
+
+ public long getRevised()
+ {
+ return revised;
+ }
+
+ public void setRevised(long revised)
+ {
+ long created = branchPoint.getTimeStamp();
+ if (revised != UNSPECIFIED_DATE && revised < Math.max(0, created))
+ {
+ throw new IllegalArgumentException("revision=" + this + ", created=" + created + ", revised=" + revised);
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting revised {0}: {1,date} {1,time,HH:mm:ss:SSS}", this, revised);
+ }
+
+ this.revised = revised;
+ }
+
+ public InternalCDORevisionDelta compare(CDORevision origin)
+ {
+ return (InternalCDORevisionDelta)CDORevisionDeltaUtil.create(origin, this);
+ }
+
+ public int compareTo(CDOBranchPoint o)
+ {
+ return branchPoint.compareTo(o);
+ }
+
+ public void merge(CDORevisionDelta delta)
+ {
+ CDORevisionMerger applier = new CDORevisionMerger();
+ applier.merge(this, delta);
+ }
+
+ public CDOID getResourceID()
+ {
+ return resourceID;
+ }
+
+ public void setResourceID(CDOID resourceID)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting resourceID {0}: {1}", this, resourceID);
+ }
+
+ this.resourceID = resourceID;
+ }
+
+ public Object getContainerID()
+ {
+ return containerID;
+ }
+
+ public void setContainerID(Object containerID)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting containerID {0}: {1}", this, containerID);
+ }
+
+ this.containerID = containerID;
+ }
+
+ public int getContainingFeatureID()
+ {
+ return containingFeatureID;
+ }
+
+ public void setContainingFeatureID(int containingFeatureID)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting containingFeatureID {0}: {1}", this, containingFeatureID);
+ }
+
+ this.containingFeatureID = containingFeatureID;
+ }
+
+ public int hashCode(EStructuralFeature feature)
+ {
+ return getValue(feature).hashCode();
+ }
+
+ public Object get(EStructuralFeature feature, int index)
+ {
+ if (feature.isMany() && index != EStore.NO_INDEX)
+ {
+ return getList(feature).get(index);
+ }
+
+ return getValue(feature);
+ }
+
+ public boolean contains(EStructuralFeature feature, Object value)
+ {
+ return getList(feature).contains(value);
+ }
+
+ public int indexOf(EStructuralFeature feature, Object value)
+ {
+ return getList(feature).indexOf(value);
+ }
+
+ public boolean isEmpty(EStructuralFeature feature)
+ {
+ return getList(feature).isEmpty();
+ }
+
+ public int lastIndexOf(EStructuralFeature feature, Object value)
+ {
+ return getList(feature).lastIndexOf(value);
+ }
+
+ public int size(EStructuralFeature feature)
+ {
+ return getList(feature).size();
+ }
+
+ public Object[] toArray(EStructuralFeature feature)
+ {
+ if (!feature.isMany())
+ {
+ throw new IllegalStateException("!feature.isMany()");
+ }
+
+ return getList(feature).toArray();
+ }
+
+ public <T> T[] toArray(EStructuralFeature feature, T[] array)
+ {
+ if (!feature.isMany())
+ {
+ throw new IllegalStateException("!feature.isMany()");
+ }
+
+ return getList(feature).toArray(array);
+ }
+
+ public void add(EStructuralFeature feature, int index, Object value)
+ {
+ getList(feature).add(index, value);
+ }
+
+ public void clear(EStructuralFeature feature)
+ {
+ setValue(feature, null);
+ }
+
+ public Object move(EStructuralFeature feature, int targetIndex, int sourceIndex)
+ {
+ return getList(feature).move(targetIndex, sourceIndex);
+ }
+
+ public Object remove(EStructuralFeature feature, int index)
+ {
+ return getList(feature).remove(index);
+ }
+
+ public Object set(EStructuralFeature feature, int index, Object value)
+ {
+ if (feature.isMany())
+ {
+ return getList(feature).set(index, value);
+ }
+
+ return setValue(feature, value);
+ }
+
+ public void unset(EStructuralFeature feature)
+ {
+ setValue(feature, null);
+ }
+
+ public void adjustReferences(CDOReferenceAdjuster revisionAdjuster)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Adjusting references for revision {0}", this);
+ }
+
+ resourceID = (CDOID)revisionAdjuster.adjustReference(resourceID);
+ containerID = revisionAdjuster.adjustReference(containerID);
+
+ EStructuralFeature[] features = classInfo.getAllPersistentFeatures();
+ for (int i = 0; i < features.length; i++)
+ {
+ EStructuralFeature feature = features[i];
+ if (feature instanceof EReference || FeatureMapUtil.isFeatureMap(feature))
+ {
+ if (feature.isMany())
+ {
+ InternalCDOList list = (InternalCDOList)getValueAsList(i);
+ if (list != null)
+ {
+ list.adjustReferences(revisionAdjuster, feature);
+ }
+ }
+ else
+ {
+ CDOType type = CDOModelUtil.getType(feature);
+ setValue(i, type.adjustReferences(revisionAdjuster, getValue(i)));
+ }
+ }
+ }
+ }
+
+ public Object getValue(EStructuralFeature feature)
+ {
+ int featureIndex = classInfo.getFeatureIndex(feature);
+ return getValue(featureIndex);
+ }
+
+ public Object setValue(EStructuralFeature feature, Object value)
+ {
+ int featureIndex = classInfo.getFeatureIndex(feature);
+
+ try
+ {
+ Object old = getValue(featureIndex);
+ setValue(featureIndex, value);
+ return old;
+ }
+ catch (ArrayIndexOutOfBoundsException ex)
+ {
+ throw new IllegalArgumentException(MessageFormat.format(Messages.getString("AbstractCDORevision.20"), feature,
+ classInfo), ex);
+ }
+ }
+
+ public CDOList getList(EStructuralFeature feature)
+ {
+ return getList(feature, 0);
+ }
+
+ public CDOList getList(EStructuralFeature feature, int size)
+ {
+ int featureIndex = classInfo.getFeatureIndex(feature);
+ CDOList list = (CDOList)getValue(featureIndex);
+ if (list == null && size != -1)
+ {
+ list = CDOListFactory.DEFAULT.createList(size, 0, 0);
+ setValue(featureIndex, list);
+ }
+
+ return list;
+ }
+
+ public void setList(EStructuralFeature feature, InternalCDOList list)
+ {
+ int featureIndex = classInfo.getFeatureIndex(feature);
+ setValue(featureIndex, list);
+ }
+
+ protected abstract void initValues(EStructuralFeature[] allPersistentFeatures);
+
+ protected abstract Object getValue(int featureIndex);
+
+ protected abstract void setValue(int featureIndex, Object value);
+
+ private CDOList getValueAsList(int i)
+ {
+ return (CDOList)getValue(i);
+ }
+
+ private void writeValues(CDODataOutput out, int referenceChunk) throws IOException
+ {
+ EClass owner = getEClass();
+ EStructuralFeature[] features = classInfo.getAllPersistentFeatures();
+ for (int i = 0; i < features.length; i++)
+ {
+ EStructuralFeature feature = features[i];
+ Object value = getValue(i);
+ if (value == null)
+ {
+ // Feature is NOT set
+ out.writeByte(UNSET);
+ continue;
+ }
+
+ // Feature IS set
+ if (value == CDORevisionData.NIL)
+ {
+ // Feature IS null
+ out.writeByte(SET_NULL);
+ continue;
+ }
+
+ // Feature is NOT null
+ out.writeByte(SET_NOT_NULL);
+ if (feature.isMany())
+ {
+ CDOList list = (CDOList)value;
+ out.writeCDOList(owner, feature, list, referenceChunk);
+ }
+ else
+ {
+ checkNoFeatureMap(feature);
+ if (value != null && feature instanceof EReference)
+ {
+ value = out.getIDProvider().provideCDOID(value);
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Writing feature {0}: {1}", feature.getName(), value);
+ }
+
+ out.writeCDOFeatureValue(feature, value);
+ }
+ }
+ }
+
+ private void readValues(CDODataInput in) throws IOException
+ {
+ EClass owner = getEClass();
+ EStructuralFeature[] features = classInfo.getAllPersistentFeatures();
+ initValues(features);
+ for (int i = 0; i < features.length; i++)
+ {
+ Object value;
+ EStructuralFeature feature = features[i];
+ byte unsetState = in.readByte();
+ switch (unsetState)
+ {
+ case UNSET:
+ continue;
+
+ case SET_NULL:
+ setValue(i, CDORevisionData.NIL);
+ continue;
+ }
+
+ if (feature.isMany())
+ {
+ value = in.readCDOList(owner, feature);
+ }
+ else
+ {
+ value = in.readCDOFeatureValue(feature);
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Read feature {0}: {1}", feature.getName(), value);
+ }
+ }
+
+ setValue(i, value);
+ }
+ }
+
+ public static void checkNoFeatureMap(EStructuralFeature feature)
+ {
+ if (FeatureMapUtil.isFeatureMap(feature))
+ {
+ throw new UnsupportedOperationException("Single-valued feature maps not yet handled");
+ }
+ }
+
+ public static Object remapID(Object value, Map<CDOIDTemp, CDOID> idMappings)
+ {
+ if (value instanceof CDOIDTemp)
+ {
+ CDOIDTemp oldID = (CDOIDTemp)value;
+ if (!oldID.isNull())
+ {
+ CDOID newID = idMappings.get(oldID);
+ if (newID == null)
+ {
+ throw new IllegalStateException(MessageFormat.format(Messages.getString("AbstractCDORevision.2"), oldID));
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Adjusting ID: {0} --> {1}", oldID, newID);
+ }
+
+ return newID;
+ }
+ }
+
+ return value;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java
new file mode 100644
index 0000000000..df912654cc
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java
@@ -0,0 +1,302 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.spi.common.revision;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDProvider;
+import org.eclipse.emf.cdo.common.io.CDODataInput;
+import org.eclipse.emf.cdo.common.io.CDODataOutput;
+import org.eclipse.emf.cdo.common.model.CDOClassInfo;
+import org.eclipse.emf.cdo.common.revision.CDOList;
+import org.eclipse.emf.cdo.common.revision.CDOReferenceAdjuster;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionData;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.io.IOException;
+
+/**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+public abstract class DelegatingCDORevision implements InternalCDORevision
+{
+ public DelegatingCDORevision()
+ {
+ }
+
+ public abstract InternalCDORevision getDelegate();
+
+ public int compareTo(CDOBranchPoint o)
+ {
+ return getDelegate().compareTo(o);
+ }
+
+ public void adjustReferences(CDOReferenceAdjuster revisionAdjuster)
+ {
+ getDelegate().adjustReferences(revisionAdjuster);
+ }
+
+ public long getTimeStamp()
+ {
+ return getDelegate().getTimeStamp();
+ }
+
+ public CDOBranch getBranch()
+ {
+ return getDelegate().getBranch();
+ }
+
+ public boolean isHistorical()
+ {
+ return getDelegate().isHistorical();
+ }
+
+ public CDOID getID()
+ {
+ return getDelegate().getID();
+ }
+
+ public CDORevision revision()
+ {
+ return getDelegate().revision();
+ }
+
+ public CDOID getResourceID()
+ {
+ return getDelegate().getResourceID();
+ }
+
+ public Object getContainerID()
+ {
+ return getDelegate().getContainerID();
+ }
+
+ public int getContainingFeatureID()
+ {
+ return getDelegate().getContainingFeatureID();
+ }
+
+ public Object get(EStructuralFeature feature, int index)
+ {
+ return getDelegate().get(feature, index);
+ }
+
+ public EClass getEClass()
+ {
+ return getDelegate().getEClass();
+ }
+
+ public int getVersion()
+ {
+ return getDelegate().getVersion();
+ }
+
+ public int size(EStructuralFeature feature)
+ {
+ return getDelegate().size(feature);
+ }
+
+ public long getRevised()
+ {
+ return getDelegate().getRevised();
+ }
+
+ public boolean isEmpty(EStructuralFeature feature)
+ {
+ return getDelegate().isEmpty(feature);
+ }
+
+ public boolean isValid(long timeStamp)
+ {
+ return getDelegate().isValid(timeStamp);
+ }
+
+ public CDOClassInfo getClassInfo()
+ {
+ return getDelegate().getClassInfo();
+ }
+
+ public void setID(CDOID id)
+ {
+ getDelegate().setID(id);
+ }
+
+ public boolean contains(EStructuralFeature feature, Object value)
+ {
+ return getDelegate().contains(feature, value);
+ }
+
+ public boolean isResourceNode()
+ {
+ return getDelegate().isResourceNode();
+ }
+
+ public void setVersion(int version)
+ {
+ getDelegate().setVersion(version);
+ }
+
+ public boolean isResourceFolder()
+ {
+ return getDelegate().isResourceFolder();
+ }
+
+ public int indexOf(EStructuralFeature feature, Object value)
+ {
+ return getDelegate().indexOf(feature, value);
+ }
+
+ public boolean isResource()
+ {
+ return getDelegate().isResource();
+ }
+
+ public void setBranchPoint(CDOBranchPoint branchPoint)
+ {
+ getDelegate().setBranchPoint(branchPoint);
+ }
+
+ public void adjustForCommit(CDOBranch branch, long timeStamp)
+ {
+ getDelegate().adjustForCommit(branch, timeStamp);
+ }
+
+ public CDORevisionData data()
+ {
+ return getDelegate().data();
+ }
+
+ public int lastIndexOf(EStructuralFeature feature, Object value)
+ {
+ return getDelegate().lastIndexOf(feature, value);
+ }
+
+ public void setRevised(long revised)
+ {
+ getDelegate().setRevised(revised);
+ }
+
+ public CDORevisionDelta compare(CDORevision origin)
+ {
+ return getDelegate().compare(origin);
+ }
+
+ public void setResourceID(CDOID resourceID)
+ {
+ getDelegate().setResourceID(resourceID);
+ }
+
+ public void merge(CDORevisionDelta delta)
+ {
+ getDelegate().merge(delta);
+ }
+
+ public <T> T[] toArray(EStructuralFeature feature, T[] array)
+ {
+ return getDelegate().toArray(feature, array);
+ }
+
+ public void setContainerID(Object containerID)
+ {
+ getDelegate().setContainerID(containerID);
+ }
+
+ public void setContainingFeatureID(int containingFeatureID)
+ {
+ getDelegate().setContainingFeatureID(containingFeatureID);
+ }
+
+ public Object[] toArray(EStructuralFeature feature)
+ {
+ return getDelegate().toArray(feature);
+ }
+
+ public void add(EStructuralFeature feature, int index, Object value)
+ {
+ getDelegate().add(feature, index, value);
+ }
+
+ public int hashCode(EStructuralFeature feature)
+ {
+ return getDelegate().hashCode(feature);
+ }
+
+ public void clear(EStructuralFeature feature)
+ {
+ getDelegate().clear(feature);
+ }
+
+ public Object move(EStructuralFeature feature, int targetIndex, int sourceIndex)
+ {
+ return getDelegate().move(feature, targetIndex, sourceIndex);
+ }
+
+ public Object remove(EStructuralFeature feature, int index)
+ {
+ return getDelegate().remove(feature, index);
+ }
+
+ public Object set(EStructuralFeature feature, int index, Object value)
+ {
+ return getDelegate().set(feature, index, value);
+ }
+
+ public void unset(EStructuralFeature feature)
+ {
+ getDelegate().unset(feature);
+ }
+
+ public Object getValue(EStructuralFeature feature)
+ {
+ return getDelegate().getValue(feature);
+ }
+
+ public Object setValue(EStructuralFeature feature, Object value)
+ {
+ return getDelegate().setValue(feature, value);
+ }
+
+ public void setList(EStructuralFeature feature, InternalCDOList list)
+ {
+ getDelegate().setList(feature, list);
+ }
+
+ public CDOList getList(EStructuralFeature feature)
+ {
+ return getDelegate().getList(feature);
+ }
+
+ public CDOList getList(EStructuralFeature feature, int size)
+ {
+ return getDelegate().getList(feature, size);
+ }
+
+ public void read(CDODataInput in) throws IOException
+ {
+ getDelegate().read(in);
+ }
+
+ public void write(CDODataOutput out, int referenceChunk) throws IOException
+ {
+ getDelegate().write(out, referenceChunk);
+ }
+
+ public void convertEObjects(CDOIDProvider oidProvider)
+ {
+ getDelegate().convertEObjects(oidProvider);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevisionManager.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevisionManager.java
new file mode 100644
index 0000000000..ef8d99261b
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevisionManager.java
@@ -0,0 +1,172 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.spi.common.revision;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionFactory;
+import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCache;
+import org.eclipse.emf.cdo.common.revision.cache.InternalCDORevisionCache;
+
+import org.eclipse.net4j.util.lifecycle.Lifecycle;
+
+import org.eclipse.emf.ecore.EClass;
+
+import java.util.List;
+
+/**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+public abstract class DelegatingCDORevisionManager extends Lifecycle implements InternalCDORevisionManager
+{
+ public DelegatingCDORevisionManager()
+ {
+ }
+
+ public InternalCDORevisionCache getCache()
+ {
+ return getDelegate().getCache();
+ }
+
+ public void setCache(CDORevisionCache cache)
+ {
+ getDelegate().setCache(cache);
+ }
+
+ public void setFactory(CDORevisionFactory factory)
+ {
+ getDelegate().setFactory(factory);
+ }
+
+ public CDORevisionFactory getFactory()
+ {
+ return getDelegate().getFactory();
+ }
+
+ public RevisionLoader getRevisionLoader()
+ {
+ return getDelegate().getRevisionLoader();
+ }
+
+ public void setRevisionLoader(RevisionLoader revisionLoader)
+ {
+ getDelegate().setRevisionLoader(revisionLoader);
+ }
+
+ public RevisionLocker getRevisionLocker()
+ {
+ return getDelegate().getRevisionLocker();
+ }
+
+ public void setRevisionLocker(RevisionLocker revisionLocker)
+ {
+ getDelegate().setRevisionLocker(revisionLocker);
+ }
+
+ public boolean isSupportingBranches()
+ {
+ return getDelegate().isSupportingBranches();
+ }
+
+ public void setSupportingBranches(boolean on)
+ {
+ getDelegate().setSupportingBranches(on);
+ }
+
+ public boolean addRevision(CDORevision revision)
+ {
+ return getDelegate().addRevision(revision);
+ }
+
+ public boolean containsRevision(CDOID id, CDOBranchPoint branchPoint)
+ {
+ return getDelegate().containsRevision(id, branchPoint);
+ }
+
+ public boolean containsRevisionByVersion(CDOID id, CDOBranchVersion branchVersion)
+ {
+ return getDelegate().containsRevisionByVersion(id, branchVersion);
+ }
+
+ public EClass getObjectType(CDOID id)
+ {
+ return getDelegate().getObjectType(id);
+ }
+
+ public CDORevision getRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int referenceChunk,
+ boolean loadOnDemand)
+ {
+ return getDelegate().getRevisionByVersion(id, branchVersion, referenceChunk, loadOnDemand);
+ }
+
+ public CDORevision getRevision(CDOID id, CDOBranchPoint branchPoint, int referenceChunk, int prefetchDepth,
+ boolean loadOnDemand)
+ {
+ return getDelegate().getRevision(id, branchPoint, referenceChunk, prefetchDepth, loadOnDemand);
+ }
+
+ public CDORevision getRevision(CDOID id, CDOBranchPoint branchPoint, int referenceChunk, int prefetchDepth,
+ boolean loadOnDemand, SyntheticCDORevision[] synthetics)
+ {
+ return getDelegate().getRevision(id, branchPoint, referenceChunk, prefetchDepth, loadOnDemand, synthetics);
+ }
+
+ public List<CDORevision> getRevisions(List<CDOID> ids, CDOBranchPoint branchPoint, int referenceChunk,
+ int prefetchDepth, boolean loadOnDemand)
+ {
+ return getDelegate().getRevisions(ids, branchPoint, referenceChunk, prefetchDepth, loadOnDemand);
+ }
+
+ public List<CDORevision> getRevisions(List<CDOID> ids, CDOBranchPoint branchPoint, int referenceChunk,
+ int prefetchDepth, boolean loadOnDemand, SyntheticCDORevision[] synthetics)
+ {
+ return getDelegate().getRevisions(ids, branchPoint, referenceChunk, prefetchDepth, loadOnDemand, synthetics);
+ }
+
+ public void reviseLatest(CDOID id, CDOBranch branch)
+ {
+ getDelegate().reviseLatest(id, branch);
+ }
+
+ public void reviseVersion(CDOID id, CDOBranchVersion branchVersion, long timeStamp)
+ {
+ getDelegate().reviseVersion(id, branchVersion, timeStamp);
+ }
+
+ @Override
+ protected void doActivate() throws Exception
+ {
+ if (isDelegatingLifecycle())
+ {
+ getDelegate().activate();
+ }
+ }
+
+ @Override
+ protected void doDeactivate() throws Exception
+ {
+ if (isDelegatingLifecycle())
+ {
+ getDelegate().deactivate();
+ }
+ }
+
+ protected boolean isDelegatingLifecycle()
+ {
+ return true;
+ }
+
+ protected abstract InternalCDORevisionManager getDelegate();
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DetachedCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DetachedCDORevision.java
new file mode 100644
index 0000000000..1037848a78
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DetachedCDORevision.java
@@ -0,0 +1,48 @@
+package org.eclipse.emf.cdo.spi.common.revision;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.id.CDOID;
+
+import java.text.MessageFormat;
+
+/**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+public class DetachedCDORevision extends SyntheticCDORevision
+{
+ private int version;
+
+ private long timeStamp;
+
+ public DetachedCDORevision(CDOID id, CDOBranch branch, int version, long timeStamp)
+ {
+ super(id, branch);
+ this.version = version;
+ this.timeStamp = timeStamp;
+ }
+
+ @Override
+ public final int getVersion()
+ {
+ return version;
+ }
+
+ @Override
+ public long getTimeStamp()
+ {
+ return timeStamp;
+ }
+
+ @Override
+ public long getRevised()
+ {
+ return UNSPECIFIED_DATE;
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("DetachedCDORevision[{0}:{1}v{2}]", getID(), getBranch().getID(), version);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java
index 74e18df90e..6fdc85cade 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java
@@ -11,6 +11,8 @@
*/
package org.eclipse.emf.cdo.spi.common.revision;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDProvider;
import org.eclipse.emf.cdo.common.io.CDODataInput;
@@ -43,9 +45,7 @@ public interface InternalCDORevision extends CDORevision, CDORevisionData, CDORe
/**
* @since 3.0
*/
- public int setTransactional(boolean on);
-
- public void setCreated(long created);
+ public void setBranchPoint(CDOBranchPoint branchPoint);
public void setRevised(long revised);
@@ -55,6 +55,11 @@ public interface InternalCDORevision extends CDORevision, CDORevisionData, CDORe
public void setContainingFeatureID(int containingFeatureID);
+ /**
+ * @since 3.0
+ */
+ public void adjustForCommit(CDOBranch branch, long timeStamp);
+
public void add(EStructuralFeature feature, int index, Object value);
public void clear(EStructuralFeature feature);
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevisionDelta.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevisionDelta.java
index 10825713ca..e295d354ee 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevisionDelta.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevisionDelta.java
@@ -4,12 +4,13 @@
* 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.spi.common.revision;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.revision.CDOReferenceAdjuster;
import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
@@ -25,7 +26,13 @@ public interface InternalCDORevisionDelta extends CDORevisionDelta
public void adjustReferences(CDOReferenceAdjuster idMappings);
- public void setOriginVersion(int originVersion);
+ /**
+ * @since 3.0
+ */
+ public void setBranch(CDOBranch branch);
- public void setDirtyVersion(int dirtyVersion);
+ /**
+ * @since 3.0
+ */
+ public void setVersion(int version);
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevisionManager.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevisionManager.java
index a37a92739e..15fb0735a3 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevisionManager.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevisionManager.java
@@ -10,22 +10,31 @@
*/
package org.eclipse.emf.cdo.spi.common.revision;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionFactory;
import org.eclipse.emf.cdo.common.revision.CDORevisionManager;
import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCache;
+import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCacheAdder;
+import org.eclipse.emf.cdo.common.revision.cache.InternalCDORevisionCache;
import org.eclipse.net4j.util.lifecycle.ILifecycle;
-import java.util.Collection;
import java.util.List;
/**
* @author Eike Stepper
* @since 3.0
*/
-public interface InternalCDORevisionManager extends CDORevisionManager, ILifecycle
+public interface InternalCDORevisionManager extends CDORevisionManager, CDORevisionCacheAdder, ILifecycle
{
+ public boolean isSupportingBranches();
+
+ public void setSupportingBranches(boolean on);
+
public RevisionLoader getRevisionLoader();
public void setRevisionLoader(RevisionLoader revisionLoader);
@@ -38,35 +47,35 @@ public interface InternalCDORevisionManager extends CDORevisionManager, ILifecyc
public void setFactory(CDORevisionFactory factory);
- public CDORevisionCache getCache();
+ public InternalCDORevisionCache getCache();
public void setCache(CDORevisionCache cache);
- public void reviseLatest(CDOID id);
+ public void reviseLatest(CDOID id, CDOBranch branch);
+
+ public void reviseVersion(CDOID id, CDOBranchVersion branchVersion, long timeStamp);
+
+ public CDORevision getRevision(CDOID id, CDOBranchPoint branchPoint, int referenceChunk, int prefetchDepth,
+ boolean loadOnDemand, SyntheticCDORevision[] synthetics);
- public void reviseVersion(CDOID id, int version, long timeStamp);
+ public List<CDORevision> getRevisions(List<CDOID> ids, CDOBranchPoint branchPoint, int referenceChunk,
+ int prefetchDepth, boolean loadOnDemand, SyntheticCDORevision[] synthetics);
/**
* @author Eike Stepper
+ * @since 3.0
*/
public interface RevisionLoader
{
- public InternalCDORevision verifyRevision(InternalCDORevision revision, int referenceChunk);
-
- public InternalCDORevision loadRevision(CDOID id, int referenceChunk, int prefetchDepth);
-
- public InternalCDORevision loadRevisionByTime(CDOID id, int referenceChunk, int prefetchDepth, long timeStamp);
-
- public InternalCDORevision loadRevisionByVersion(CDOID id, int referenceChunk, int prefetchDepth, int version);
-
- public List<InternalCDORevision> loadRevisions(Collection<CDOID> ids, int referenceChunk, int prefetchDepth);
+ public List<InternalCDORevision> loadRevisions(List<RevisionInfo> infos, CDOBranchPoint branchPoint,
+ int referenceChunk, int prefetchDepth);
- public List<InternalCDORevision> loadRevisionsByTime(Collection<CDOID> ids, int referenceChunk, int prefetchDepth,
- long timeStamp);
+ public InternalCDORevision loadRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int referenceChunk);
}
/**
* @author Eike Stepper
+ * @since 3.0
*/
public interface RevisionLocker
{
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/PointerCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/PointerCDORevision.java
new file mode 100644
index 0000000000..4d803fe87f
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/PointerCDORevision.java
@@ -0,0 +1,71 @@
+package org.eclipse.emf.cdo.spi.common.revision;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.common.id.CDOID;
+
+import java.text.MessageFormat;
+
+/**
+ * A {@link SyntheticCDORevision synthetic} revision that represents the initial period of an object in a
+ * {@link CDOBranch branch} when the object is still associated with a revision from one of the baseline branches. It
+ * always has {@link #getVersion() version} {@link CDOBranchVersion#UNSPECIFIED_VERSION zero} and can only appear in
+ * branches below the {@link CDOBranch#isMainBranch() main} branch.
+ *
+ * @author Eike Stepper
+ * @since 3.0
+ */
+public class PointerCDORevision extends SyntheticCDORevision
+{
+ private long revised = UNSPECIFIED_DATE;
+
+ private CDOBranchVersion target;
+
+ public PointerCDORevision(CDOID id, CDOBranch branch, long revised, CDOBranchVersion target)
+ {
+ super(id, branch);
+ this.revised = revised;
+ this.target = target;
+ }
+
+ @Override
+ public final int getVersion()
+ {
+ return UNSPECIFIED_VERSION;
+ }
+
+ @Override
+ public long getTimeStamp()
+ {
+ return getBranch().getBase().getTimeStamp();
+ }
+
+ @Override
+ public long getRevised()
+ {
+ return revised;
+ }
+
+ @Override
+ public void setRevised(long revised)
+ {
+ this.revised = revised;
+ }
+
+ public CDOBranchVersion getTarget()
+ {
+ return target;
+ }
+
+ @Override
+ public String toString()
+ {
+ if (target == null)
+ {
+ return MessageFormat.format("PointerCDORevision[{0}:{1}v0 --> null]", getID(), getBranch().getID());
+ }
+
+ return MessageFormat.format("PointerCDORevision[{0}:{1}v0 --> {2}v{3}]", getID(), getBranch().getID(), target
+ .getBranch().getID(), target.getVersion());
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/RevisionInfo.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/RevisionInfo.java
new file mode 100644
index 0000000000..3fd408ac45
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/RevisionInfo.java
@@ -0,0 +1,539 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.spi.common.revision;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.common.id.CDOID;
+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.net4j.util.CheckUtil;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+public abstract class RevisionInfo
+{
+ private static final int NO_RESULT = 0;
+
+ private static final int POINTER_RESULT = 1;
+
+ private static final int DETACHED_RESULT = 2;
+
+ private static final int NORMAL_RESULT = 3;
+
+ private CDOID id;
+
+ private CDOBranchPoint requestedBranchPoint;
+
+ private InternalCDORevision result;
+
+ private SyntheticCDORevision synthetic;
+
+ protected RevisionInfo(CDOID id, CDOBranchPoint requestedBranchPoint)
+ {
+ CheckUtil.checkArg(requestedBranchPoint, "requestedBranchPoint");
+ this.id = id;
+ this.requestedBranchPoint = requestedBranchPoint;
+ }
+
+ protected RevisionInfo(CDODataInput in, CDOBranchPoint requestedBranchPoint) throws IOException
+ {
+ CheckUtil.checkArg(requestedBranchPoint, "requestedBranchPoint");
+ id = in.readCDOID();
+ this.requestedBranchPoint = requestedBranchPoint;
+ }
+
+ public abstract Type getType();
+
+ public final CDOID getID()
+ {
+ return id;
+ }
+
+ public final CDOBranchPoint getRequestedBranchPoint()
+ {
+ return requestedBranchPoint;
+ }
+
+ public InternalCDORevision getResult()
+ {
+ return result;
+ }
+
+ public void setResult(InternalCDORevision result)
+ {
+ this.result = result;
+ }
+
+ public SyntheticCDORevision getSynthetic()
+ {
+ return synthetic;
+ }
+
+ public void setSynthetic(SyntheticCDORevision synthetic)
+ {
+ this.synthetic = synthetic;
+ }
+
+ public abstract boolean isLoadNeeded();
+
+ public void write(CDODataOutput out) throws IOException
+ {
+ out.writeByte(getType().ordinal());
+ out.writeCDOID(getID());
+ }
+
+ public static RevisionInfo read(CDODataInput in, CDOBranchPoint requestedBranchPoint) throws IOException
+ {
+ byte ordinal = in.readByte();
+ Type type = Type.values()[ordinal];
+ switch (type)
+ {
+ case AVAILABLE_NORMAL:
+ return new Available.Normal(in, requestedBranchPoint);
+
+ case AVAILABLE_POINTER:
+ return new Available.Pointer(in, requestedBranchPoint);
+
+ case AVAILABLE_DETACHED:
+ return new Available.Detached(in, requestedBranchPoint);
+
+ case MISSING:
+ return new Missing(in, requestedBranchPoint);
+
+ default:
+ throw new IOException("Invalid revision info type: " + type);
+ }
+ }
+
+ public void execute(InternalCDORevisionManager revisionManager, int referenceChunk)
+ {
+ SyntheticCDORevision[] synthetics = new SyntheticCDORevision[1];
+ result = (InternalCDORevision)revisionManager.getRevision(getID(), requestedBranchPoint, referenceChunk,
+ CDORevision.DEPTH_NONE, true, synthetics);
+ synthetic = synthetics[0];
+ }
+
+ public void writeResult(CDODataOutput out, int referenceChunk) throws IOException
+ {
+ writeRevision(out, referenceChunk);
+ doWriteResult(out, synthetic, referenceChunk);
+ }
+
+ public void readResult(CDODataInput in) throws IOException
+ {
+ readRevision(in);
+ synthetic = (SyntheticCDORevision)doReadResult(in);
+ }
+
+ public void processResult(InternalCDORevisionManager revisionManager, List<CDORevision> results,
+ SyntheticCDORevision[] synthetics, int i)
+ {
+ if (result instanceof DetachedCDORevision)
+ {
+ results.add(null);
+ }
+ else
+ {
+ results.add(result);
+ }
+
+ if (result != null)
+ {
+ revisionManager.addRevision(result);
+ }
+
+ if (synthetic != null)
+ {
+ revisionManager.addRevision(synthetic);
+ if (synthetic instanceof PointerCDORevision)
+ {
+ PointerCDORevision pointer = (PointerCDORevision)synthetic;
+ CDOBranchVersion target = pointer.getTarget();
+ if (target != result && target instanceof InternalCDORevision)
+ {
+ revisionManager.addRevision((CDORevision)target);
+ }
+ }
+
+ if (synthetics != null)
+ {
+ synthetics[i] = synthetic;
+ }
+ }
+ }
+
+ protected void writeRevision(CDODataOutput out, int referenceChunk) throws IOException
+ {
+ out.writeCDORevision(result, referenceChunk);
+ }
+
+ protected void readRevision(CDODataInput in) throws IOException
+ {
+ result = (InternalCDORevision)in.readCDORevision();
+ }
+
+ protected void doWriteResult(CDODataOutput out, InternalCDORevision revision, int referenceChunk) throws IOException
+ {
+ if (revision == null)
+ {
+ out.writeByte(NO_RESULT);
+ }
+ else if (revision instanceof PointerCDORevision)
+ {
+ PointerCDORevision pointer = (PointerCDORevision)revision;
+ out.writeByte(POINTER_RESULT);
+ out.writeLong(pointer.getRevised());
+
+ CDOBranchVersion target = pointer.getTarget();
+ if (target instanceof InternalCDORevision)
+ {
+ doWriteResult(out, (InternalCDORevision)target, referenceChunk);
+ }
+ else
+ {
+ out.writeByte(NO_RESULT);
+ }
+ }
+ else if (revision instanceof DetachedCDORevision)
+ {
+ DetachedCDORevision detached = (DetachedCDORevision)revision;
+ out.writeByte(DETACHED_RESULT);
+ out.writeLong(detached.getTimeStamp());
+ out.writeInt(detached.getVersion());
+ }
+ else
+ {
+ out.writeByte(NORMAL_RESULT);
+ out.writeCDORevision(revision, referenceChunk);
+ }
+ }
+
+ protected InternalCDORevision doReadResult(CDODataInput in) throws IOException
+ {
+ byte type = in.readByte();
+ switch (type)
+ {
+ case NO_RESULT:
+ return null;
+
+ case POINTER_RESULT:
+ {
+ long revised = in.readLong();
+ InternalCDORevision target = doReadResult(in);
+ return new PointerCDORevision(id, requestedBranchPoint.getBranch(), revised, target);
+ }
+
+ case DETACHED_RESULT:
+ {
+ long timeStamp = in.readLong();
+ int version = in.readInt();
+ return new DetachedCDORevision(id, requestedBranchPoint.getBranch(), version, timeStamp);
+ }
+
+ case NORMAL_RESULT:
+ return (InternalCDORevision)in.readCDORevision();
+
+ default:
+ throw new IllegalStateException("Invalid synthetic type: " + type);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+ public static enum Type
+ {
+ AVAILABLE_NORMAL, AVAILABLE_POINTER, AVAILABLE_DETACHED, MISSING
+ }
+
+ /**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+ public static abstract class Available extends RevisionInfo
+ {
+ private CDOBranchVersion availableBranchVersion;
+
+ protected Available(CDOID id, CDOBranchPoint requestedBranchPoint, CDOBranchVersion availableBranchVersion)
+ {
+ super(id, requestedBranchPoint);
+ this.availableBranchVersion = availableBranchVersion;
+ }
+
+ protected Available(CDODataInput in, CDOBranchPoint requestedBranchPoint) throws IOException
+ {
+ super(in, requestedBranchPoint);
+ availableBranchVersion = in.readCDOBranchVersion();
+ }
+
+ public CDOBranchVersion getAvailableBranchVersion()
+ {
+ return availableBranchVersion;
+ }
+
+ public boolean isDirect()
+ {
+ return availableBranchVersion.getBranch() == getRequestedBranchPoint().getBranch();
+ }
+
+ @Override
+ public boolean isLoadNeeded()
+ {
+ return !isDirect();
+ }
+
+ @Override
+ public void write(CDODataOutput out) throws IOException
+ {
+ super.write(out);
+ out.writeCDOBranchVersion(availableBranchVersion);
+ }
+
+ @Override
+ protected void writeRevision(CDODataOutput out, int referenceChunk) throws IOException
+ {
+ InternalCDORevision result = getResult();
+ if (result != null && result.getBranch() == availableBranchVersion.getBranch())
+ {
+ // Use available
+ out.writeBoolean(true);
+ }
+ else
+ {
+ out.writeBoolean(false);
+ super.writeRevision(out, referenceChunk);
+ }
+ }
+
+ @Override
+ protected void readRevision(CDODataInput in) throws IOException
+ {
+ boolean useAvailable = in.readBoolean();
+ if (useAvailable)
+ {
+ setResult((InternalCDORevision)availableBranchVersion);
+ }
+ else
+ {
+ super.readRevision(in);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+ public static class Normal extends Available
+ {
+ public Normal(CDOID id, CDOBranchPoint requestedBranchPoint, CDOBranchVersion availableBranchVersion)
+ {
+ super(id, requestedBranchPoint, availableBranchVersion);
+ }
+
+ private Normal(CDODataInput in, CDOBranchPoint requestedBranchPoint) throws IOException
+ {
+ super(in, requestedBranchPoint);
+ }
+
+ @Override
+ public Type getType()
+ {
+ return Type.AVAILABLE_NORMAL;
+ }
+
+ @Override
+ public InternalCDORevision getResult()
+ {
+ if (isDirect())
+ {
+ return (InternalCDORevision)getAvailableBranchVersion();
+ }
+
+ return super.getResult();
+ }
+
+ @Override
+ public void processResult(InternalCDORevisionManager revisionManager, List<CDORevision> results,
+ SyntheticCDORevision[] synthetics, int i)
+ {
+ if (!isLoadNeeded())
+ {
+ setResult((InternalCDORevision)getAvailableBranchVersion());
+ }
+
+ super.processResult(revisionManager, results, synthetics, i);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+ public static class Pointer extends Available
+ {
+ private CDOBranchVersion targetBranchVersion;
+
+ private boolean hasTarget;
+
+ public Pointer(CDOID id, CDOBranchPoint requestedBranchPoint, CDOBranchVersion availableBranchVersion,
+ CDOBranchVersion targetBranchVersion)
+ {
+ super(id, requestedBranchPoint, availableBranchVersion);
+ this.targetBranchVersion = targetBranchVersion;
+ hasTarget = targetBranchVersion instanceof InternalCDORevision;
+ }
+
+ private Pointer(CDODataInput in, CDOBranchPoint requestedBranchPoint) throws IOException
+ {
+ super(in, requestedBranchPoint);
+ if (in.readBoolean())
+ {
+ targetBranchVersion = in.readCDOBranchVersion();
+ hasTarget = in.readBoolean();
+ }
+ }
+
+ public CDOBranchVersion getTargetBranchVersion()
+ {
+ return targetBranchVersion;
+ }
+
+ @Override
+ public Type getType()
+ {
+ return Type.AVAILABLE_POINTER;
+ }
+
+ public boolean hasTarget()
+ {
+ return hasTarget;
+ }
+
+ @Override
+ public boolean isLoadNeeded()
+ {
+ if (getRequestedBranchPoint().getBranch().isMainBranch())
+ {
+ return false;
+ }
+
+ return !isDirect() || !hasTarget();
+ }
+
+ @Override
+ public void write(CDODataOutput out) throws IOException
+ {
+ super.write(out);
+ if (targetBranchVersion != null)
+ {
+ out.writeBoolean(true);
+ out.writeCDOBranchVersion(targetBranchVersion);
+ out.writeBoolean(hasTarget);
+ }
+ else
+ {
+ out.writeBoolean(false);
+ }
+ }
+
+ @Override
+ public void processResult(InternalCDORevisionManager revisionManager, List<CDORevision> results,
+ SyntheticCDORevision[] synthetics, int i)
+ {
+ if (!isLoadNeeded())
+ {
+ CDOBranchVersion target = getTargetBranchVersion();
+ if (target instanceof InternalCDORevision)
+ {
+ setResult((InternalCDORevision)target);
+ }
+
+ setSynthetic((PointerCDORevision)getAvailableBranchVersion());
+ }
+
+ super.processResult(revisionManager, results, synthetics, i);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+ public static class Detached extends Available
+ {
+ public Detached(CDOID id, CDOBranchPoint requestedBranchPoint, CDOBranchVersion availableBranchVersion)
+ {
+ super(id, requestedBranchPoint, availableBranchVersion);
+ }
+
+ private Detached(CDODataInput in, CDOBranchPoint requestedBranchPoint) throws IOException
+ {
+ super(in, requestedBranchPoint);
+ }
+
+ @Override
+ public Type getType()
+ {
+ return Type.AVAILABLE_DETACHED;
+ }
+
+ @Override
+ public void processResult(InternalCDORevisionManager revisionManager, List<CDORevision> results,
+ SyntheticCDORevision[] synthetics, int i)
+ {
+ if (!isLoadNeeded())
+ {
+ setSynthetic((DetachedCDORevision)getAvailableBranchVersion());
+ }
+
+ super.processResult(revisionManager, results, synthetics, i);
+ }
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+ public static class Missing extends RevisionInfo
+ {
+ public Missing(CDOID id, CDOBranchPoint requestedBranchPoint)
+ {
+ super(id, requestedBranchPoint);
+ }
+
+ private Missing(CDODataInput in, CDOBranchPoint requestedBranchPoint) throws IOException
+ {
+ super(in, requestedBranchPoint);
+ }
+
+ @Override
+ public Type getType()
+ {
+ return Type.MISSING;
+ }
+
+ @Override
+ public boolean isLoadNeeded()
+ {
+ return true;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java
new file mode 100644
index 0000000000..04890cd89e
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java
@@ -0,0 +1,258 @@
+/**
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.spi.common.revision;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDProvider;
+import org.eclipse.emf.cdo.common.io.CDODataInput;
+import org.eclipse.emf.cdo.common.io.CDODataOutput;
+import org.eclipse.emf.cdo.common.model.CDOClassInfo;
+import org.eclipse.emf.cdo.common.revision.CDOList;
+import org.eclipse.emf.cdo.common.revision.CDOReferenceAdjuster;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.io.IOException;
+
+/**
+ * @author Eike Stepper
+ * @since 3.0
+ */
+public class StubCDORevision extends AbstractCDORevision
+{
+ public StubCDORevision()
+ {
+ }
+
+ public int compareTo(CDOBranchPoint o)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public CDOClassInfo getClassInfo()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setID(CDOID id)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setVersion(int version)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setBranchPoint(CDOBranchPoint branchPoint)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setRevised(long revised)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setResourceID(CDOID resourceID)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setContainerID(Object containerID)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setContainingFeatureID(int containingFeatureID)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void add(EStructuralFeature feature, int index, Object value)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void clear(EStructuralFeature feature)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object move(EStructuralFeature feature, int targetIndex, int sourceIndex)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object remove(EStructuralFeature feature, int index)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object set(EStructuralFeature feature, int index, Object value)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void unset(EStructuralFeature feature)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object getValue(EStructuralFeature feature)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object setValue(EStructuralFeature feature, Object value)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setList(EStructuralFeature feature, InternalCDOList list)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public CDOList getList(EStructuralFeature feature)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public CDOList getList(EStructuralFeature feature, int size)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void read(CDODataInput in) throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void write(CDODataOutput out, int referenceChunk) throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void convertEObjects(CDOIDProvider oidProvider)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public int getVersion()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public long getRevised()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public CDORevisionDelta compare(CDORevision origin)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void merge(CDORevisionDelta delta)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public CDORevision copy()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public CDOID getID()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public CDOBranch getBranch()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public long getTimeStamp()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public CDOID getResourceID()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object getContainerID()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public int getContainingFeatureID()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object get(EStructuralFeature feature, int index)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public int size(EStructuralFeature feature)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isEmpty(EStructuralFeature feature)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean contains(EStructuralFeature feature, Object value)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public int indexOf(EStructuralFeature feature, Object value)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public int lastIndexOf(EStructuralFeature feature, Object value)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public <T> T[] toArray(EStructuralFeature feature, T[] array)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object[] toArray(EStructuralFeature feature)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public int hashCode(EStructuralFeature feature)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void adjustReferences(CDOReferenceAdjuster revisionAdjuster)
+ {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/SyntheticCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/SyntheticCDORevision.java
new file mode 100644
index 0000000000..8150ae77df
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/SyntheticCDORevision.java
@@ -0,0 +1,51 @@
+package org.eclipse.emf.cdo.spi.common.revision;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.revision.CDORevisionManager;
+import org.eclipse.emf.cdo.common.revision.cache.CDORevisionCache;
+
+/**
+ * A synthetic revision that represents the initial period of an object in a {@link CDOBranch branch} when the object is
+ * still associated with a revision from one of the baseline branches. It always has {@link #getVersion() version}
+ * {@link CDOBranchVersion#UNSPECIFIED_VERSION zero} and can only appear in branches below the
+ * {@link CDOBranch#isMainBranch() main} branch.
+ * <p>
+ * Synthetic revisions are used for two slightly different purposes:
+ * <ol>
+ * <li>For {@link CDORevisionCache cache} optimization.
+ * <li>As a persistent "detach marker" indicating that the first modification of an object in a branch is its deletion.
+ * </ol>
+ * <p>
+ * Instances of this marker revision are not supposed to be exposed outside of a revision {@link CDORevisionManager
+ * manager}. They are mainly used in the communication between a revision manager and its associated revision
+ * {@link InternalCDORevisionManager.RevisionLoader loader}.
+ *
+ * @author Eike Stepper
+ * @since 3.0
+ */
+public abstract class SyntheticCDORevision extends StubCDORevision
+{
+ private CDOID id;
+
+ private CDOBranch branch;
+
+ public SyntheticCDORevision(CDOID id, CDOBranch branch)
+ {
+ this.id = id;
+ this.branch = branch;
+ }
+
+ @Override
+ public CDOID getID()
+ {
+ return id;
+ }
+
+ @Override
+ public CDOBranch getBranch()
+ {
+ return branch;
+ }
+}

Back to the top