Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon McDuff2008-09-11 06:38:38 +0000
committerSimon McDuff2008-09-11 06:38:38 +0000
commit65087f87d7d13b3d1b79f5aa3a0086e23a137d0b (patch)
tree6cbd5ba0450b6ed791c407207033ed8fe0e18afd /plugins
parent128d02f77c213ee2aca3ecd23ef6bba7a16dfa09 (diff)
downloadcdo-65087f87d7d13b3d1b79f5aa3a0086e23a137d0b.tar.gz
cdo-65087f87d7d13b3d1b79f5aa3a0086e23a137d0b.tar.xz
cdo-65087f87d7d13b3d1b79f5aa3a0086e23a137d0b.zip
[213402] Support external references
https://bugs.eclipse.org/bugs/show_bug.cgi?id=213402
Diffstat (limited to 'plugins')
-rw-r--r--plugins/org.eclipse.emf.cdo.common/.settings/.api_filters59
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOProtocolConstants.java21
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOID.java20
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDExternal.java21
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDTemp.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDTempMeta.java22
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDUtil.java28
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionData.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/delta/CDOContainerFeatureDelta.java14
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDODataInputImpl.java9
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDExternalImpl.java99
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDExternalTempImpl.java31
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDNullImpl.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempMetaImpl.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/query/AbstractQueryResult.java1
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionImpl.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOContainerFeatureDeltaImpl.java46
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java7
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionMerger.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractCDOID.java25
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractCDOIDInteger.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractCDOIDLong.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/InternalCDORevision.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.doc/new/new.htm57
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ClassMapping.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreWriter.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernatePackageHandler.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStoreWriter.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionProxy.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.server/.settings/.api_filters22
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/CommitManager.java163
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/MEMStore.java8
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/MEMStoreAccessor.java55
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/NotificationManager.java32
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/QueryHandlerFactory.java12
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/QueryManager.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java24
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java27
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/StoreAccessor.java69
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Transaction.java427
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContextImpl.java527
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/XATransactionCommitContext.java122
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CDOServerProtocol.java13
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitNotificationRequest.java12
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionCancelIndication.java70
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionIndication.java153
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionPhase1Indication.java75
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionPhase2Indication.java101
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionPhase3Indication.java59
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/INotificationManager.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStore.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreWriter.java26
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ITransaction.java12
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractCDOTest.java9
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTests.java6
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AutoAttacherTest.java1
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ComplexTest.java36
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ContainmentTest.java152
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/DetachTest.java274
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ExternalReferenceTest.java334
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/InitialTest.java53
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/InvalidationTest.java60
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ResourceTest.java156
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/RevisionHolderTest.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StateMachineTest.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ViewTest.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/XATransactionTest.java222
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_246622_Test.java135
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/logic/TestLogic.java36
-rw-r--r--plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java4
-rw-r--r--plugins/org.eclipse.emf.cdo/.settings/.api_filters63
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOSavepoint.java5
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransaction.java50
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransactionHandler.java2
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOUserTransaction.java42
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOView.java12
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOViewSet.java37
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOXATransaction.java39
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/CDOResourceFactory.java4
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceFactoryImpl.java42
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java116
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOURIUtil.java125
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOUtil.java113
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOAbstractSavepoint.java92
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOCallbackImpl.java2
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOCommitContext.java51
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOLegacyImpl.java39
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java267
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSavepointImpl.java275
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java75
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSingleTransactionStrategy.java92
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java214
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStore.java119
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java573
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionStrategy.java32
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java349
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewSetImpl.java314
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOXASavepoint.java41
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOXATransactionCommitContext.java156
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOXATransactionImpl.java606
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/InternalCDOTransaction.java33
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitNotificationIndication.java14
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionCancelRequest.java57
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionPhase1Request.java64
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionPhase2Request.java120
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionPhase3Request.java65
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionRequest.java98
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CDOViewSetPackageRegistryImpl.java83
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/FSMUtil.java60
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/RevisionAdjuster.java9
111 files changed, 7014 insertions, 1557 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/.settings/.api_filters b/plugins/org.eclipse.emf.cdo.common/.settings/.api_filters
new file mode 100644
index 0000000000..a9baf602c1
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/.settings/.api_filters
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<component id="org.eclipse.emf.cdo.common" version="2">
+ <resource path="src/org/eclipse/emf/cdo/common/model/CDOType.java" type="org.eclipse.emf.cdo.common.model.CDOType">
+ <filter id="1211105284">
+ <message_arguments>
+ <message_argument value="org.eclipse.emf.cdo.common.model.CDOType"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/emf/cdo/common/CDODataOutput.java" type="org.eclipse.emf.cdo.common.CDODataOutput">
+ <filter id="1110441988">
+ <message_arguments>
+ <message_argument value="org.eclipse.emf.cdo.common.CDODataOutput"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/emf/cdo/common/revision/CDORevisionData.java" type="org.eclipse.emf.cdo.common.revision.CDORevisionData">
+ <filter id="1211105284">
+ <message_arguments>
+ <message_argument value="org.eclipse.emf.cdo.common.revision.CDORevisionData"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/emf/cdo/common/analyzer/CDOFetchRule.java" type="org.eclipse.emf.cdo.common.analyzer.CDOFetchRule">
+ <filter id="1143996420">
+ <message_arguments>
+ <message_argument value="org.eclipse.emf.cdo.common.analyzer.CDOFetchRule"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/emf/cdo/spi/common/InternalCDOModelElement.java" type="org.eclipse.emf.cdo.spi.common.InternalCDOModelElement">
+ <filter id="1211105284">
+ <message_arguments>
+ <message_argument value="org.eclipse.emf.cdo.spi.common.InternalCDOModelElement"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/emf/cdo/common/CDODataInput.java" type="org.eclipse.emf.cdo.common.CDODataInput">
+ <filter id="1110441988">
+ <message_arguments>
+ <message_argument value="org.eclipse.emf.cdo.common.CDODataInput"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/emf/cdo/spi/common/InternalCDORevision.java" type="org.eclipse.emf.cdo.spi.common.InternalCDORevision">
+ <filter id="1211105284">
+ <message_arguments>
+ <message_argument value="org.eclipse.emf.cdo.spi.common.InternalCDORevision"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/emf/cdo/common/revision/delta/CDOContainerFeatureDelta.java" type="org.eclipse.emf.cdo.common.revision.delta.CDOContainerFeatureDelta">
+ <filter id="1211105284">
+ <message_arguments>
+ <message_argument value="org.eclipse.emf.cdo.common.revision.delta.CDOContainerFeatureDelta"/>
+ </message_arguments>
+ </filter>
+ </resource>
+</component>
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOProtocolConstants.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOProtocolConstants.java
index f184e2e844..96cea83c46 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOProtocolConstants.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOProtocolConstants.java
@@ -9,6 +9,7 @@
* Eike Stepper - initial API and implementation
* Simon McDuff - http://bugs.eclipse.org/230832
* Simon McDuff - http://bugs.eclipse.org/233490
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.common;
@@ -73,6 +74,26 @@ public interface CDOProtocolConstants
*/
public static final short SIGNAL_CHANGE_SUBSCRIPTION = 19;
+ /**
+ * @since 2.0
+ */
+ public static final short SIGNAL_COMMIT_TRANSACTION_PHASE1 = 20;
+
+ /**
+ * @since 2.0
+ */
+ public static final short SIGNAL_COMMIT_TRANSACTION_PHASE2 = 21;
+
+ /**
+ * @since 2.0
+ */
+ public static final short SIGNAL_COMMIT_TRANSACTION_PHASE3 = 22;
+
+ /**
+ * @since 2.0
+ */
+ public static final short SIGNAL_COMMIT_TRANSACTION_CANCEL = 23;
+
public static final int ERROR_REPOSITORY_NOT_FOUND = -1;
public static final int ERROR_NO_SESSION = -2;
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOID.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOID.java
index 264a9b205c..b18c3c8607 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOID.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOID.java
@@ -8,6 +8,7 @@
* Contributors:
* Eike Stepper - initial API and implementation
* Simon McDuff - http://bugs.eclipse.org/226778
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.common.id;
@@ -36,13 +37,28 @@ public interface CDOID extends Serializable
/**
* @since 2.0
*/
- public String asString();
+ public boolean isExternal();
+
+ /**
+ * @since 2.0
+ */
+ public String toURIFragment();
/**
* @author Eike Stepper
*/
public enum Type
{
- NULL, OBJECT, LEGACY_OBJECT, TEMP_OBJECT, META, TEMP_META
+ NULL, OBJECT,
+
+ /**
+ * @since 2.0
+ */
+ EXTERNAL_OBJECT,
+
+ /**
+ * @since 2.0
+ */
+ EXTERNAL_TEMP_OBJECT, LEGACY_OBJECT, TEMP_OBJECT, META, TEMP_META
}
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDExternal.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDExternal.java
new file mode 100644
index 0000000000..690b694512
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDExternal.java
@@ -0,0 +1,21 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo.common.id;
+
+/**
+ * @author Simon McDuff
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @since 2.0
+ */
+public interface CDOIDExternal extends CDOID
+{
+ String getURI();
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDTemp.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDTemp.java
index 0ffe15fad4..fe2a2575d0 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDTemp.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDTemp.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.common.id;
@@ -16,5 +17,4 @@ package org.eclipse.emf.cdo.common.id;
*/
public interface CDOIDTemp extends CDOID
{
- public int getIntValue();
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDTempMeta.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDTempMeta.java
new file mode 100644
index 0000000000..219f7b6b2a
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/id/CDOIDTempMeta.java
@@ -0,0 +1,22 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ * Simon McDuff - http://bugs.eclipse.org/213402
+ **************************************************************************/
+package org.eclipse.emf.cdo.common.id;
+
+/**
+ * @author Eike Stepper
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @since 2.0
+ */
+public interface CDOIDTempMeta extends CDOIDTemp
+{
+ public int getIntValue();
+}
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 43f080c1a5..f963b1ac0f 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
@@ -8,6 +8,7 @@
* Contributors:
* Eike Stepper - initial API and implementation
* Simon McDuff - http://bugs.eclipse.org/226778
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.common.id;
@@ -16,6 +17,8 @@ import org.eclipse.emf.cdo.common.model.CDOClassRef;
import org.eclipse.emf.cdo.common.model.CDOModelUtil;
import org.eclipse.emf.cdo.internal.common.bundle.OM;
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.CDOIDExternalTempImpl;
import org.eclipse.emf.cdo.internal.common.id.CDOIDMetaImpl;
import org.eclipse.emf.cdo.internal.common.id.CDOIDMetaRangeImpl;
import org.eclipse.emf.cdo.internal.common.id.CDOIDTempMetaImpl;
@@ -32,6 +35,7 @@ import java.io.IOException;
/**
* @author Eike Stepper
+ * @since 2.0
*/
public final class CDOIDUtil
{
@@ -83,7 +87,23 @@ public final class CDOIDUtil
{
return new CDOIDTempObjectImpl(value);
}
+
+ /**
+ * @since 2.0
+ */
+ public static CDOIDExternal createExternal(String uri)
+ {
+ return new CDOIDExternalImpl(uri);
+ }
+ /**
+ * @since 2.0
+ */
+ public static CDOIDExternal createExternalTemp(String uri)
+ {
+ return new CDOIDExternalTempImpl(uri);
+ }
+
public static CDOID createLong(long value)
{
if (value == 0L)
@@ -135,6 +155,12 @@ public final class CDOIDUtil
case META:
return new CDOIDMetaImpl(Long.valueOf(fragment));
+ case EXTERNAL_OBJECT:
+ return new CDOIDExternalImpl(fragment);
+
+ case EXTERNAL_TEMP_OBJECT:
+ return new CDOIDExternalTempImpl(fragment);
+
case OBJECT:
{
CDOIDObject id = factory.createCDOIDObject(fragment);
@@ -205,7 +231,7 @@ public final class CDOIDUtil
throw new ImplementationError();
}
- builder.append("/" + id.asString());
+ builder.append("/" + id.toURIFragment());
}
public static CDOIDMeta createMeta(long value)
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionData.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionData.java
index 6775d72f41..e9a38de333 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionData.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionData.java
@@ -23,7 +23,7 @@ public interface CDORevisionData
public CDOID getResourceID();
- public CDOID getContainerID();
+ public Object getContainerID();
public int getContainingFeatureID();
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/delta/CDOContainerFeatureDelta.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/delta/CDOContainerFeatureDelta.java
index 152682c294..79c7855103 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/delta/CDOContainerFeatureDelta.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/delta/CDOContainerFeatureDelta.java
@@ -8,10 +8,12 @@
* Contributors:
* Simon McDuff - initial API and implementation
* Eike Stepper - maintenance
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.common.revision.delta;
import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.model.CDOFeature;
/**
* @author Simon McDuff
@@ -19,7 +21,17 @@ import org.eclipse.emf.cdo.common.id.CDOID;
*/
public interface CDOContainerFeatureDelta extends CDOFeatureDelta
{
- public CDOID getContainerID();
+ /**
+ * @since 2.0
+ */
+ public static final CDOFeature CONTAINER_FEATURE = new org.eclipse.emf.cdo.internal.common.revision.delta.CDOContainerFeatureDeltaImpl.ContainerFeature();
+
+ /**
+ * @since 2.0
+ */
+ public CDOID getResourceID();
+
+ public Object getContainerID();
public int getContainerFeatureID();
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDODataInputImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDODataInputImpl.java
index da6007500f..0be5e2ccc7 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDODataInputImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDODataInputImpl.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.internal.common;
@@ -31,6 +32,8 @@ 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.CDOIDAndVersionImpl;
+import org.eclipse.emf.cdo.internal.common.id.CDOIDExternalImpl;
+import org.eclipse.emf.cdo.internal.common.id.CDOIDExternalTempImpl;
import org.eclipse.emf.cdo.internal.common.id.CDOIDMetaImpl;
import org.eclipse.emf.cdo.internal.common.id.CDOIDMetaRangeImpl;
import org.eclipse.emf.cdo.internal.common.id.CDOIDTempMetaImpl;
@@ -284,6 +287,12 @@ public abstract class CDODataInputImpl implements CDODataInput
case META:
return new CDOIDMetaImpl(readLong());
+ case EXTERNAL_OBJECT:
+ return new CDOIDExternalImpl(readString());
+
+ case EXTERNAL_TEMP_OBJECT:
+ return new CDOIDExternalTempImpl(readString());
+
case OBJECT:
{
CDOIDObject id = getIDFactory().createCDOIDObject(this);
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDExternalImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDExternalImpl.java
new file mode 100644
index 0000000000..5b0387da0f
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDExternalImpl.java
@@ -0,0 +1,99 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.common.id;
+
+import org.eclipse.emf.cdo.common.id.CDOIDExternal;
+import org.eclipse.emf.cdo.spi.common.AbstractCDOID;
+
+import org.eclipse.net4j.util.ObjectUtil;
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+import org.eclipse.net4j.util.io.ExtendedDataOutput;
+
+import java.io.IOException;
+
+/**
+ * @author Simon McDuff
+ */
+public class CDOIDExternalImpl extends AbstractCDOID implements CDOIDExternal
+{
+ private static final long serialVersionUID = 1L;
+
+ private String uri;
+
+ public CDOIDExternalImpl(String uri)
+ {
+ this.uri = uri;
+ }
+
+ public String getURI()
+ {
+ return uri;
+ }
+
+ public Type getType()
+ {
+ return Type.EXTERNAL_OBJECT;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "oid" + toURIFragment();
+ }
+
+ @Override
+ public void read(String fragmentPart)
+ {
+ uri = fragmentPart;
+ }
+
+ @Override
+ public void read(ExtendedDataInput in) throws IOException
+ {
+ uri = in.readString();
+ }
+
+ @Override
+ public void write(ExtendedDataOutput out) throws IOException
+ {
+ out.writeString(uri);
+ }
+
+ public String toURIFragment()
+ {
+ return uri;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+ // Could CDOIDExternalTempImpl and CDOIDExternalImpl have the same uri. We don't want to mixed them.
+ if (obj != null && obj.getClass() == getClass())
+ {
+ CDOIDExternal that = (CDOIDExternal)obj;
+ return ObjectUtil.equals(getURI(), that.getURI());
+ }
+
+ return false;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return getClass().hashCode() ^ uri.hashCode();
+ }
+
+
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDExternalTempImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDExternalTempImpl.java
new file mode 100644
index 0000000000..b1e3601b29
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDExternalTempImpl.java
@@ -0,0 +1,31 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.common.id;
+
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+
+/**
+ * @author Simon McDuff
+ */
+public class CDOIDExternalTempImpl extends CDOIDExternalImpl implements CDOIDTemp
+{
+ private static final long serialVersionUID = 1L;
+
+ public CDOIDExternalTempImpl(String uri)
+ {
+ super(uri);
+ }
+
+ public Type getType()
+ {
+ return Type.EXTERNAL_TEMP_OBJECT;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDNullImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDNullImpl.java
index f62a38faae..ba21a1b9d4 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDNullImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDNullImpl.java
@@ -61,7 +61,7 @@ public final class CDOIDNullImpl extends AbstractCDOID implements CDOIDMeta, CDO
return null;
}
- public String asString()
+ public String toURIFragment()
{
return "NULL";
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempMetaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempMetaImpl.java
index 0d5b94a6fd..63c7d27ef6 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempMetaImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempMetaImpl.java
@@ -7,16 +7,17 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.internal.common.id;
-import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.common.id.CDOIDTempMeta;
import org.eclipse.emf.cdo.spi.common.AbstractCDOIDInteger;
/**
* @author Eike Stepper
*/
-public class CDOIDTempMetaImpl extends AbstractCDOIDInteger implements CDOIDTemp
+public class CDOIDTempMetaImpl extends AbstractCDOIDInteger implements CDOIDTempMeta
{
private static final long serialVersionUID = 1L;
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/query/AbstractQueryResult.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/query/AbstractQueryResult.java
index dfd97a8926..3f659670b0 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/query/AbstractQueryResult.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/query/AbstractQueryResult.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
**************************************************************************/
package org.eclipse.emf.cdo.internal.common.query;
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 4f9343087d..dcb170782f 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
@@ -9,6 +9,7 @@
* Eike Stepper - initial API and implementation
* Simon McDuff - http://bugs.eclipse.org/201266
* Simon McDuff - http://bugs.eclipse.org/212958
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.internal.common.revision;
@@ -66,7 +67,7 @@ public class CDORevisionImpl implements InternalCDORevision
private CDOID resourceID;
- private CDOID containerID;
+ private Object containerID;
private int containingFeatureID;
@@ -145,7 +146,8 @@ public class CDORevisionImpl implements InternalCDORevision
out.writeLong(created);
out.writeLong(revised);
out.writeCDOID(resourceID);
- out.writeCDOID(containerID);
+ containerID = out.getIDProvider().provideCDOID(containerID);
+ out.writeCDOID((CDOID)containerID);
out.writeInt(containingFeatureID);
writeValues(out, referenceChunk);
WRITING.stop(this);
@@ -298,12 +300,12 @@ public class CDORevisionImpl implements InternalCDORevision
this.resourceID = resourceID;
}
- public CDOID getContainerID()
+ public Object getContainerID()
{
return containerID;
}
- public void setContainerID(CDOID containerID)
+ public void setContainerID(Object containerID)
{
if (TRACER.isEnabled())
{
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOContainerFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOContainerFeatureDeltaImpl.java
index eed6a6272b..d5d21ece13 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOContainerFeatureDeltaImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOContainerFeatureDeltaImpl.java
@@ -8,6 +8,8 @@
* Contributors:
* Simon McDuff - initial API and implementation
* Eike Stepper - maintenance
+ * Simon McDuff - http://bugs.eclipse.org/204890
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.internal.common.revision.delta;
@@ -35,18 +37,16 @@ import java.util.Map;
*/
public class CDOContainerFeatureDeltaImpl extends CDOFeatureDeltaImpl implements CDOContainerFeatureDelta
{
- /**
- * TODO Move to CDOObjectContainerFeature
- */
- private static CDOFeature CONTAINER_FEATURE = new ContainerFeature();
+ private CDOID newResourceID;
- private CDOID newContainerID;
+ private Object newContainerID;
private int newContainerFeatureID;
- public CDOContainerFeatureDeltaImpl(CDOID newContainerID, int newContainerFeatureID)
+ public CDOContainerFeatureDeltaImpl(CDOID newResourceID, Object newContainerID, int newContainerFeatureID)
{
super(CONTAINER_FEATURE);
+ this.newResourceID = newResourceID;
this.newContainerID = newContainerID;
this.newContainerFeatureID = newContainerFeatureID;
}
@@ -55,34 +55,33 @@ public class CDOContainerFeatureDeltaImpl extends CDOFeatureDeltaImpl implements
{
super(CONTAINER_FEATURE);
newContainerFeatureID = in.readInt();
- newContainerID = in.readCDOID();
+ newContainerID = in.readCDOID();
+ newResourceID = in.readCDOID();
}
- @Override
- public void write(CDODataOutput out, CDOClass cdoClass) throws IOException
+ public Type getType()
{
- out.writeInt(getType().ordinal());
- out.writeInt(newContainerFeatureID);
- out.writeCDOID(newContainerID);
+ return Type.CONTAINER;
}
- public int getContainerFeatureID()
+ public CDOID getResourceID()
{
- return newContainerFeatureID;
+ return newResourceID;
}
- public CDOID getContainerID()
+ public Object getContainerID()
{
return newContainerID;
}
- public Type getType()
+ public int getContainerFeatureID()
{
- return Type.CONTAINER;
+ return newContainerFeatureID;
}
public void apply(CDORevision revision)
{
+ ((InternalCDORevision)revision).setResourceID(newResourceID);
((InternalCDORevision)revision).setContainerID(newContainerID);
((InternalCDORevision)revision).setContainingFeatureID(newContainerFeatureID);
}
@@ -90,9 +89,20 @@ public class CDOContainerFeatureDeltaImpl extends CDOFeatureDeltaImpl implements
@Override
public void adjustReferences(Map<CDOIDTemp, CDOID> idMappings)
{
+ newResourceID = (CDOID)CDORevisionUtil.remapID(newResourceID, idMappings);
newContainerID = (CDOID)CDORevisionUtil.remapID(newContainerID, idMappings);
}
+ @Override
+ public void write(CDODataOutput out, CDOClass cdoClass) throws IOException
+ {
+ out.writeInt(getType().ordinal());
+ out.writeInt(newContainerFeatureID);
+ newContainerID = out.getIDProvider().provideCDOID(newContainerID);
+ out.writeCDOID((CDOID)newContainerID);
+ out.writeCDOID(newResourceID);
+ }
+
public void accept(CDOFeatureDeltaVisitor visitor)
{
visitor.visit(this);
@@ -101,7 +111,7 @@ public class CDOContainerFeatureDeltaImpl extends CDOFeatureDeltaImpl implements
/**
* @author Simon McDuff
*/
- private static final class ContainerFeature implements CDOFeature
+ public static final class ContainerFeature implements CDOFeature
{
public CDOClass getContainingClass()
{
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 d18464681c..e6b97bea0c 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
@@ -8,6 +8,7 @@
* Contributors:
* Eike Stepper - initial API and implementation
* Simon McDuff - http://bugs.eclipse.org/201266
+ * Simon McDuff - http://bugs.eclipse.org/204890
**************************************************************************/
package org.eclipse.emf.cdo.internal.common.revision.delta;
@@ -71,9 +72,11 @@ public class CDORevisionDeltaImpl implements InternalCDORevisionDelta
CDORevisionData originData = originRevision.getData();
CDORevisionData dirtyData = dirtyRevision.getData();
if (!compare(originData.getContainerID(), dirtyData.getContainerID())
- || !compare(originData.getContainingFeatureID(), dirtyData.getContainingFeatureID()))
+ || !compare(originData.getContainingFeatureID(), dirtyData.getContainingFeatureID())
+ || !compare(originData.getResourceID(), dirtyData.getResourceID()))
{
- addFeatureDelta(new CDOContainerFeatureDeltaImpl(dirtyData.getContainerID(), dirtyData.getContainingFeatureID()));
+ addFeatureDelta(new CDOContainerFeatureDeltaImpl(dirtyData.getResourceID(), dirtyData.getContainerID(), dirtyData
+ .getContainingFeatureID()));
}
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionMerger.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionMerger.java
index d1300ae653..a6af879935 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionMerger.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionMerger.java
@@ -8,6 +8,7 @@
* Contributors:
* Simon McDuff - initial API and implementation
* Eike Stepper - maintenance
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.internal.common.revision.delta;
@@ -78,6 +79,7 @@ public class CDORevisionMerger extends CDOFeatureDeltaVisitorImpl
@Override
public void visit(CDOContainerFeatureDelta delta)
{
+ revision.setResourceID(delta.getResourceID());
revision.setContainerID(delta.getContainerID());
revision.setContainingFeatureID(delta.getContainerFeatureID());
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractCDOID.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractCDOID.java
index 40c9ee33e0..0afaf5979c 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractCDOID.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractCDOID.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.spi.common;
@@ -34,6 +35,7 @@ public abstract class AbstractCDOID implements CDOID
{
case NULL:
return true;
+
default:
return false;
}
@@ -47,6 +49,7 @@ public abstract class AbstractCDOID implements CDOID
case LEGACY_OBJECT:
case TEMP_OBJECT:
return true;
+
default:
return false;
}
@@ -58,6 +61,7 @@ public abstract class AbstractCDOID implements CDOID
{
case LEGACY_OBJECT:
return true;
+
default:
return false;
}
@@ -70,6 +74,7 @@ public abstract class AbstractCDOID implements CDOID
case META:
case TEMP_META:
return true;
+
default:
return false;
}
@@ -81,14 +86,32 @@ public abstract class AbstractCDOID implements CDOID
{
case TEMP_OBJECT:
case TEMP_META:
+ case EXTERNAL_TEMP_OBJECT:
+ return true;
+
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * @since 2.0
+ */
+ public boolean isExternal()
+ {
+ switch (getType())
+ {
+ case EXTERNAL_TEMP_OBJECT:
+ case EXTERNAL_OBJECT:
return true;
+
default:
return false;
}
}
/**
- * CDOID.asString and AbstractCDOID.read(String) need to match
+ * <b>Note:</b> {@link CDOID#toURIFragment()} and {@link AbstractCDOID#read(String)} need to match.
*
* @since 2.0
*/
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractCDOIDInteger.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractCDOIDInteger.java
index ac34f569fc..41145191f9 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractCDOIDInteger.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractCDOIDInteger.java
@@ -47,7 +47,7 @@ public abstract class AbstractCDOIDInteger extends AbstractCDOID implements Comp
/**
* @since 2.0
*/
- public String asString()
+ public String toURIFragment()
{
return String.valueOf(value);
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractCDOIDLong.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractCDOIDLong.java
index 25ee8f4509..5b21e48ba4 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractCDOIDLong.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractCDOIDLong.java
@@ -48,7 +48,7 @@ public abstract class AbstractCDOIDLong extends AbstractCDOID implements Compara
/**
* @since 2.0
*/
- public String asString()
+ public String toURIFragment()
{
return String.valueOf(value);
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/InternalCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/InternalCDORevision.java
index 0c128acee1..b2153833d3 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/InternalCDORevision.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/InternalCDORevision.java
@@ -42,7 +42,7 @@ public interface InternalCDORevision extends CDORevision, CDORevisionData
public void setResourceID(CDOID resourceID);
- public void setContainerID(CDOID containerID);
+ public void setContainerID(Object containerID);
public void setContainingFeatureID(int containingFeatureID);
diff --git a/plugins/org.eclipse.emf.cdo.doc/new/new.htm b/plugins/org.eclipse.emf.cdo.doc/new/new.htm
index ff2560e6a0..edd38df51d 100644
--- a/plugins/org.eclipse.emf.cdo.doc/new/new.htm
+++ b/plugins/org.eclipse.emf.cdo.doc/new/new.htm
@@ -111,11 +111,62 @@ xmlns="http://www.w3.org/1999/xhtml"><HEAD><TITLE>CDO - New Features</TITLE>
<TD vAlign=top align=left width="200" bgColor=#e0d0e6>
<P align=right><b>Support getURIFragment and getEObject</b></P></TD>
<TD vAlign=top>
- <P align=left>CDOResource now supports getURIFragment and getEObject. </P>
+ <P align=left>CDOResource now supports the getURIFragment and getEObject methods. </P>
<P align=left><b>Note:</b> The URIs of temporary objects will
- change when the <i>CDOTransaction</i> is committed . Objects will no
- longer be accessible using their temporary URI once <i>the CDOTransaction</i> is
+ change when the <i>CDOTransaction</i> is committed. Objects will no
+ longer be accessible using their temporary URI once the <i>CDOTransaction</i> is
committed.</P></TD></TR>
</TBODY></TABLE>
+ <HR>
+
+<TABLE id=table418 cellSpacing=0 cellPadding=10>
+ <TBODY>
+ <TR>
+ <TD vAlign=top align=left width="200" bgColor=#e0d0e6>
+ <P align=right><b>Support external references</b></P></TD>
+ <TD vAlign=top>
+ <p>CDO supports many resources from different sources in the same resource set. Objects can refer to each other even if they are not from the same store or source.</p>
+ <ul>
+ <li>An object from XMIResource can refer to objects from CDOResource.</li>
+ <li>An object from CDOResource can refer to objects from XMIResource.</li>
+ <li>An object from CDOResourceA (repositoryA) can refer to objects from another CDOResourceB(repositoryB)</li>
+ </ul>
+ <p>Each resource set has a CDOViewSet. A CDOViewSet could have many CDOViews but each CDOView refers to one CDOViewSet only.</p>
+ <p>To use that feature, the same resource set must be used when opening CDOView.</p>
+ <p>e.g.:
+ <i>ResourceSet resourceSet = new ResourceSetImpl();</i><br>
+ <i>CDOTransaction transactionA1 = sessionA.openTransaction(resourceSet);</i><br>
+ <i>CDOTransaction transactionB1 = sessionB.openTransaction(resourceSet);</i>
+ </p>
+ <p><b>Note:</b> Two CDOViews from the same repository cannot belong to the same resource set.</p></TD></TR>
+ </TBODY></TABLE>
+ <HR>
+
+<TABLE id=table418 cellSpacing=0 cellPadding=10>
+ <TBODY>
+ <TR>
+ <TD vAlign=top align=left width="200" bgColor=#e0d0e6>
+ <P align=right><b>XATransaction</b></P></TD>
+ <TD vAlign=top></i><p>This feature provides the ability to use many transactions from many repositories as a whole instead of individually. Its three-phase commit allows the clients to commit circular graphs and complex graphs that are from multiple repositories or CDOTransactions.</p>
+ <p>e.g.:<br>
+ <i>CDOXATransaction xaTransaction = CDOUtil.createXATransaction();</i><br>
+ <i>CDOUtil.prepareResourceSet(resourceSet);</i><br>
+ <i>xaTransaction.add(CDOUtil.getViewSet(resourceSet));</i><br>
+ <i>xaTransaction.setSavepoint();</i><br>
+ <i>xaTransaction.rollback();</i><br>
+ <i>xaTransaction.commit();</i>
+</TD></TR>
+ </TBODY></TABLE>
+ <HR>
+
+<TABLE id=table418 cellSpacing=0 cellPadding=10>
+ <TBODY>
+ <TR>
+ <TD vAlign=top align=left width="200" bgColor=#e0d0e6>
+ <P align=right><b>Support containment proxies</b></P></TD>
+ <TD vAlign=top></i><p>This feature provides the ability to have an object that is in resourceA and its container could be in another resource. The object and container are in different resource and it does support external references as wellThis is to be in line with EMF. However, it needs to be define in your model.</p>
+ <p>
+</TD></TR>
+ </TBODY></TABLE>
</BODY>
</HTML> \ No newline at end of file
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ClassMapping.java
index 68334b411d..012449dde5 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ClassMapping.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/ClassMapping.java
@@ -10,6 +10,7 @@
**************************************************************************/
package org.eclipse.emf.cdo.server.internal.db;
+import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.model.CDOClass;
import org.eclipse.emf.cdo.common.model.CDOFeature;
@@ -155,7 +156,7 @@ public abstract class ClassMapping implements IClassMapping
builder.append(", ");
builder.append(CDOIDUtil.getLong(revision.getResourceID()));
builder.append(", ");
- builder.append(CDOIDUtil.getLong(revision.getContainerID()));
+ builder.append(CDOIDUtil.getLong((CDOID)revision.getContainerID()));
builder.append(", ");
builder.append(revision.getContainingFeatureID());
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreWriter.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreWriter.java
index df8ed692ec..956e9dd0e1 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreWriter.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreWriter.java
@@ -47,9 +47,9 @@ public class DBStoreWriter extends DBStoreReader implements IDBStoreWriter
}
@Override
- public void commit(CommitContext context)
+ public void commit()
{
- super.commit(context);
+ super.commit();
try
{
diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernatePackageHandler.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernatePackageHandler.java
index 1386ffab76..610dcedac0 100644
--- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernatePackageHandler.java
+++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernatePackageHandler.java
@@ -16,6 +16,7 @@ import org.eclipse.emf.cdo.common.model.CDOClassProxy;
import org.eclipse.emf.cdo.common.model.CDOFeature;
import org.eclipse.emf.cdo.common.model.CDOPackage;
import org.eclipse.emf.cdo.common.model.CDOPackageInfo;
+import org.eclipse.emf.cdo.internal.server.TransactionCommitContextImpl;
import org.eclipse.emf.cdo.server.IStoreWriter.CommitContext;
import org.eclipse.emf.cdo.server.internal.hibernate.bundle.OM;
import org.eclipse.emf.cdo.spi.common.InternalCDOClass;
@@ -80,9 +81,9 @@ public class HibernatePackageHandler extends Lifecycle
if (HibernateThreadContext.isHibernateCommitContextSet())
{
CommitContext cc = HibernateThreadContext.getHibernateCommitContext().getCommitContext();
- if (cc instanceof org.eclipse.emf.cdo.internal.server.Transaction)
+ if (cc instanceof TransactionCommitContextImpl)
{
- org.eclipse.emf.cdo.internal.server.Transaction tx = (org.eclipse.emf.cdo.internal.server.Transaction)cc;
+ TransactionCommitContextImpl tx = (TransactionCommitContextImpl)cc;
for (CDOPackage cdoPackage : tx.getNewPackages())
{
cdoPackages.add(cdoPackage);
diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStoreWriter.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStoreWriter.java
index d09c9aca4c..9a7484c02b 100644
--- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStoreWriter.java
+++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStoreWriter.java
@@ -49,7 +49,7 @@ public class HibernateStoreWriter extends HibernateStoreReader implements IHiber
}
@Override
- public void commit(CommitContext context)
+ public void write(CommitContext context)
{
if (TRACER.isEnabled())
{
@@ -76,7 +76,7 @@ public class HibernateStoreWriter extends HibernateStoreReader implements IHiber
{
if (cdoRevision instanceof InternalCDORevision)
{
- final CDOID containerID = ((InternalCDORevision)cdoRevision).getContainerID();
+ final CDOID containerID = (CDOID)((InternalCDORevision)cdoRevision).getContainerID();
if (!containerID.isNull() && containerID instanceof CDOIDTemp)
{
repairContainerIDs.add((InternalCDORevision)cdoRevision);
@@ -112,7 +112,7 @@ public class HibernateStoreWriter extends HibernateStoreReader implements IHiber
// now do an update of the container without incrementing the version
for (InternalCDORevision cdoRevision : repairContainerIDs)
{
- final CDORevision container = HibernateUtil.getInstance().getCDORevision(cdoRevision.getContainerID());
+ final CDORevision container = HibernateUtil.getInstance().getCDORevision((CDOID)cdoRevision.getContainerID());
final String entityName = HibernateUtil.getInstance().getEntityName(cdoRevision);
final CDOIDHibernate id = (CDOIDHibernate)cdoRevision.getID();
final CDOIDHibernate containerID = (CDOIDHibernate)container.getID();
diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionProxy.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionProxy.java
index 0c1ccdc93d..56cd88114e 100644
--- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionProxy.java
+++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionProxy.java
@@ -89,7 +89,7 @@ public class CDORevisionProxy implements HibernateProxy, InternalCDORevision, Se
return li.getRevision().getCDOClass();
}
- public CDOID getContainerID()
+ public Object getContainerID()
{
return li.getRevision().getContainerID();
}
@@ -219,7 +219,7 @@ public class CDORevisionProxy implements HibernateProxy, InternalCDORevision, Se
return li.getRevision().set(feature, index, value);
}
- public void setContainerID(CDOID containerID)
+ public void setContainerID(Object containerID)
{
li.getRevision().setContainerID(containerID);
}
diff --git a/plugins/org.eclipse.emf.cdo.server/.settings/.api_filters b/plugins/org.eclipse.emf.cdo.server/.settings/.api_filters
index 13b4c4be87..b3f04b71e9 100644
--- a/plugins/org.eclipse.emf.cdo.server/.settings/.api_filters
+++ b/plugins/org.eclipse.emf.cdo.server/.settings/.api_filters
@@ -64,6 +64,21 @@
</message_arguments>
</filter>
</resource>
+ <resource path="src/org/eclipse/emf/cdo/internal/server/TransactionCommitContextImpl.java" type="org.eclipse.emf.cdo.internal.server.TransactionCommitContextImpl$TransactionPackageManager">
+ <filter id="574619656">
+ <message_arguments>
+ <message_argument value="CDOPackageManager"/>
+ <message_argument value="TransactionPackageManager"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/emf/cdo/internal/server/ResourcesQueryHandler.java" type="org.eclipse.emf.cdo.internal.server.ResourcesQueryHandler">
+ <filter id="1110441988">
+ <message_arguments>
+ <message_argument value="org.eclipse.emf.cdo.internal.server.ResourcesQueryHandler"/>
+ </message_arguments>
+ </filter>
+ </resource>
<resource path="src/org/eclipse/emf/cdo/internal/server/Transaction.java" type="org.eclipse.emf.cdo.internal.server.Transaction$TransactionPackageManager">
<filter id="574619656">
<message_arguments>
@@ -87,6 +102,13 @@
</message_arguments>
</filter>
</resource>
+ <resource path="src/org/eclipse/emf/cdo/server/StoreThreadLocal.java" type="org.eclipse.emf.cdo.server.StoreThreadLocal">
+ <filter id="1110441988">
+ <message_arguments>
+ <message_argument value="org.eclipse.emf.cdo.server.StoreThreadLocal"/>
+ </message_arguments>
+ </filter>
+ </resource>
<resource path="src/org/eclipse/emf/cdo/server/IView.java" type="org.eclipse.emf.cdo.server.IView">
<filter id="574619656">
<message_arguments>
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/CommitManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/CommitManager.java
new file mode 100644
index 0000000000..dc2cc04632
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/CommitManager.java
@@ -0,0 +1,163 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.server;
+
+import org.eclipse.emf.cdo.internal.server.Transaction.InternalCommitContext;
+import org.eclipse.emf.cdo.server.IRepositoryElement;
+
+import org.eclipse.net4j.util.lifecycle.Lifecycle;
+
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+/**
+ * @author Simon McDuff
+ * @since 2.0
+ */
+public class CommitManager extends Lifecycle implements IRepositoryElement
+{
+ private Repository repository;
+
+ private ExecutorService executors;
+
+ private Map<Transaction, TransactionCommitContextEntry> commitContextMap = new ConcurrentHashMap<Transaction, TransactionCommitContextEntry>();
+
+ public CommitManager(Repository repository)
+ {
+ this.repository = repository;
+ }
+
+ public Repository getRepository()
+ {
+ return repository;
+ }
+
+ public synchronized ExecutorService getExecutors()
+ {
+ if (executors == null)
+ {
+ executors = Executors.newFixedThreadPool(10);
+ }
+
+ return executors;
+ }
+
+ public void setExecutors(ExecutorService executors)
+ {
+ this.executors = executors;
+ }
+
+ /**
+ * Create a future to execute commitContext in a different thread.
+ */
+ public void preCommit(InternalCommitContext commitContext)
+ {
+ TransactionCommitContextEntry contextEntry = new TransactionCommitContextEntry();
+ contextEntry.setContext(commitContext);
+
+ Future<Object> future = getExecutors().submit(contextEntry.createCallable());
+
+ contextEntry.setFuture(future);
+
+ commitContextMap.put(commitContext.getTransaction(), contextEntry);
+ }
+
+ /**
+ * Called after a commitContext is done successfully or not.
+ */
+ public void remove(InternalCommitContext commitContext)
+ {
+ commitContextMap.remove(commitContext.getTransaction());
+ }
+
+ public void rollback(InternalCommitContext commitContext)
+ {
+ TransactionCommitContextEntry contextEntry = commitContextMap.get(commitContext.getTransaction());
+ if (contextEntry != null)
+ {
+ contextEntry.getFuture().cancel(true);
+ commitContext.postCommit(false);
+ }
+ }
+
+ /**
+ * Waiting for a commit to be done.
+ */
+ public void waitForTermination(Transaction transaction) throws InterruptedException, ExecutionException
+ {
+ TransactionCommitContextEntry contextEntry = commitContextMap.get(transaction);
+ contextEntry.getFuture().get();
+ }
+
+ public InternalCommitContext get(Transaction transaction)
+ {
+ TransactionCommitContextEntry contextEntry = commitContextMap.get(transaction);
+ if (contextEntry != null)
+ {
+ return contextEntry.getContext();
+ }
+ return null;
+
+ }
+
+ /**
+ * @author Simon McDuff
+ */
+ private static final class TransactionCommitContextEntry
+ {
+ private InternalCommitContext context;
+
+ private Future<Object> future;
+
+ public TransactionCommitContextEntry()
+ {
+ }
+
+ public Callable<Object> createCallable()
+ {
+ return new Callable<Object>()
+ {
+
+ public Object call() throws Exception
+ {
+ context.write();
+ return null;
+ }
+ };
+ }
+
+ public InternalCommitContext getContext()
+ {
+ return context;
+ }
+
+ public void setContext(InternalCommitContext context)
+ {
+ this.context = context;
+ }
+
+ public Future<Object> getFuture()
+ {
+ return future;
+ }
+
+ public void setFuture(Future<Object> future)
+ {
+ this.future = future;
+ }
+
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/MEMStore.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/MEMStore.java
index f797efbd69..e5f02e3c8f 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/MEMStore.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/MEMStore.java
@@ -170,6 +170,14 @@ public class MEMStore extends LongIDStore implements IMEMStore
return false;
}
+ /**
+ * @since 2.0
+ */
+ public synchronized void removeID(CDOID id)
+ {
+ revisions.remove(id);
+ }
+
public synchronized CDORevision getResource(String path)
{
CDOPathFeature pathFeature = getRepository().getPackageManager().getCDOResourcePackage().getCDOResourceClass()
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/MEMStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/MEMStoreAccessor.java
index 9261c76614..0b3ecc57eb 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/MEMStoreAccessor.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/MEMStoreAccessor.java
@@ -8,6 +8,7 @@
* Contributors:
* Simon McDuff - initial API and implementation
* Eike Stepper - maintenance
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.internal.server;
@@ -137,12 +138,12 @@ public class MEMStoreAccessor extends StoreAccessor implements IStoreReader, ISt
}
@Override
- public void commit(CommitContext context)
+ public void write(CommitContext context)
{
MEMStore store = getStore();
synchronized (store)
{
- super.commit(context);
+ super.write(context);
}
}
@@ -160,6 +161,34 @@ public class MEMStoreAccessor extends StoreAccessor implements IStoreReader, ISt
}
}
+ @Override
+ protected void writePackages(CDOPackage... cdoPackages)
+ {
+ // Do nothing
+ }
+
+ @Override
+ protected void writeRevision(CDORevision revision)
+ {
+ newRevisions.add(revision);
+ getStore().addRevision(revision);
+ }
+
+ @Override
+ protected void writeRevisionDelta(CDORevisionDelta revisionDelta)
+ {
+ CDORevision revision = getStore().getRevision(revisionDelta.getID());
+ CDORevision newRevision = CDORevisionUtil.copy(revision);
+ revisionDelta.apply(newRevision);
+ writeRevision(newRevision);
+ }
+
+ @Override
+ protected void detachObject(CDOID id)
+ {
+ getStore().removeID(id);
+ }
+
/**
* @since 2.0
*/
@@ -229,28 +258,6 @@ public class MEMStoreAccessor extends StoreAccessor implements IStoreReader, ISt
}
@Override
- protected void writePackages(CDOPackage... cdoPackages)
- {
- // Do nothing
- }
-
- @Override
- protected void writeRevision(CDORevision revision)
- {
- newRevisions.add(revision);
- getStore().addRevision(revision);
- }
-
- @Override
- protected void writeRevisionDelta(CDORevisionDelta revisionDelta)
- {
- CDORevision revision = getStore().getRevision(revisionDelta.getID());
- CDORevision newRevision = CDORevisionUtil.copy(revision);
- revisionDelta.apply(newRevision);
- writeRevision(newRevision);
- }
-
- @Override
protected void doActivate() throws Exception
{
// Do nothing
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/NotificationManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/NotificationManager.java
index 32c9d5b7d1..ca6df2ddbf 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/NotificationManager.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/NotificationManager.java
@@ -11,6 +11,7 @@
**************************************************************************/
package org.eclipse.emf.cdo.internal.server;
+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.delta.CDORevisionDelta;
@@ -35,24 +36,37 @@ public class NotificationManager extends Lifecycle implements INotificationManag
this.repository = repository;
}
+ public Repository getRepository()
+ {
+ return repository;
+ }
+
public void notifyCommit(Session session, CommitContext commitContext)
{
- CDORevisionDelta[] dirtyID = commitContext.getDirtyObjectDeltas();
- int modifications = dirtyID == null ? 0 : dirtyID.length;
- if (modifications > 0)
+ CDORevisionDelta[] arrayOfDeltas = commitContext.getDirtyObjectDeltas();
+ CDOID[] arrayOfDetachedObjects = commitContext.getDetachedObjects();
+
+ int dirtyIDSize = arrayOfDeltas == null ? 0 : arrayOfDeltas.length;
+ int detachedObjectsSize = arrayOfDetachedObjects == null ? 0 : arrayOfDetachedObjects.length;
+
+ if (dirtyIDSize > 0 || detachedObjectsSize > 0)
{
- List<CDOIDAndVersion> dirtyIDs = new ArrayList<CDOIDAndVersion>(modifications);
- List<CDORevisionDelta> deltas = new ArrayList<CDORevisionDelta>(modifications);
- for (int i = 0; i < modifications; i++)
+ List<CDOIDAndVersion> dirtyIDs = new ArrayList<CDOIDAndVersion>(dirtyIDSize);
+ List<CDORevisionDelta> deltas = new ArrayList<CDORevisionDelta>(dirtyIDSize);
+ for (int i = 0; i < dirtyIDSize; i++)
{
- CDORevisionDelta delta = dirtyID[i];
+ CDORevisionDelta delta = arrayOfDeltas[i];
CDOIDAndVersion dirtyIDAndVersion = CDOIDUtil.createIDAndVersion(delta.getID(), delta.getOriginVersion());
dirtyIDs.add(dirtyIDAndVersion);
deltas.add(delta);
}
-
+ List<CDOID> detachedObjects = new ArrayList<CDOID>(detachedObjectsSize);
+ for (int i = 0; i < detachedObjectsSize; i++)
+ {
+ detachedObjects.add(arrayOfDetachedObjects[i]);
+ }
SessionManager sessionManager = repository.getSessionManager();
- sessionManager.handleCommitNotification(commitContext.getTimeStamp(), dirtyIDs, deltas, session);
+ sessionManager.handleCommitNotification(commitContext.getTimeStamp(), dirtyIDs, detachedObjects, deltas, session);
}
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/QueryHandlerFactory.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/QueryHandlerFactory.java
index 6160aa3675..81edf256da 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/QueryHandlerFactory.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/QueryHandlerFactory.java
@@ -1,3 +1,13 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ **************************************************************************/
package org.eclipse.emf.cdo.internal.server;
import org.eclipse.net4j.util.factory.Factory;
@@ -13,4 +23,4 @@ public abstract class QueryHandlerFactory extends Factory
{
super(PRODUCT_GROUP, language);
}
-} \ No newline at end of file
+}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/QueryManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/QueryManager.java
index a9ae0c8fbd..ada07a612a 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/QueryManager.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/QueryManager.java
@@ -15,6 +15,7 @@ import org.eclipse.emf.cdo.common.query.CDOQueryInfo;
import org.eclipse.emf.cdo.internal.server.bundle.OM;
import org.eclipse.emf.cdo.server.IQueryContext;
import org.eclipse.emf.cdo.server.IQueryHandler;
+import org.eclipse.emf.cdo.server.IRepositoryElement;
import org.eclipse.emf.cdo.server.IView;
import org.eclipse.net4j.util.container.SingleDeltaContainerEvent;
@@ -34,7 +35,7 @@ import java.util.concurrent.Future;
* @author Simon McDuff
* @since 2.0
*/
-public class QueryManager extends Lifecycle
+public class QueryManager extends Lifecycle implements IRepositoryElement
{
private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_SESSION, QueryManager.class);
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
index 540753049f..3136eb8f54 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
@@ -69,6 +69,8 @@ public class Repository extends Container<IRepositoryElement> implements IReposi
private NotificationManager notificationManager = createNotificationManager();
+ private CommitManager commitManager = createCommitManager();
+
private IQueryHandlerProvider queryHandlerProvider;
private IRepositoryElement[] elements;
@@ -198,6 +200,14 @@ public class Repository extends Container<IRepositoryElement> implements IReposi
/**
* @since 2.0
*/
+ public CommitManager getCommitManager()
+ {
+ return commitManager;
+ }
+
+ /**
+ * @since 2.0
+ */
public IQueryHandlerProvider getQueryHandlerProvider()
{
return queryHandlerProvider;
@@ -317,6 +327,14 @@ public class Repository extends Container<IRepositoryElement> implements IReposi
return new NotificationManager(this);
}
+ /**
+ * @since 2.0
+ */
+ protected CommitManager createCommitManager()
+ {
+ return new CommitManager(this);
+ }
+
@Override
protected void doBeforeActivate() throws Exception
{
@@ -341,7 +359,8 @@ public class Repository extends Container<IRepositoryElement> implements IReposi
throw new IllegalStateException("Store without auditing support");
}
- elements = new IRepositoryElement[] { packageManager, sessionManager, resourceManager, revisionManager, store };
+ elements = new IRepositoryElement[] { packageManager, sessionManager, resourceManager, revisionManager,
+ queryManager, notificationManager, commitManager, store };
}
@Override
@@ -375,17 +394,20 @@ public class Repository extends Container<IRepositoryElement> implements IReposi
LifecycleUtil.activate(revisionManager);
LifecycleUtil.activate(queryManager);
LifecycleUtil.activate(notificationManager);
+ LifecycleUtil.activate(commitManager);
LifecycleUtil.activate(queryHandlerProvider);
}
protected void deactivateRepository()
{
LifecycleUtil.deactivate(queryHandlerProvider);
+ LifecycleUtil.deactivate(commitManager);
LifecycleUtil.deactivate(notificationManager);
LifecycleUtil.deactivate(queryManager);
LifecycleUtil.deactivate(revisionManager);
LifecycleUtil.deactivate(resourceManager);
LifecycleUtil.deactivate(sessionManager);
+
LifecycleUtil.deactivate(packageManager);
LifecycleUtil.deactivate(store);
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java
index 15fe3109b6..dc86e2c3aa 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java
@@ -10,6 +10,7 @@
* Simon McDuff - http://bugs.eclipse.org/201266
* Simon McDuff - http://bugs.eclipse.org/230832
* Simon McDuff - http://bugs.eclipse.org/233490
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.internal.server;
@@ -170,25 +171,6 @@ public class Session extends Container<IView> implements ISession, CDOIDProvider
return view;
}
- /**
- * For tests only.
- */
- public Transaction openTransaction(int viewID, final long timeStamp)
- {
- Transaction transaction = new Transaction(this, viewID)
- {
- @Override
- protected long createTimeStamp()
- {
- return timeStamp;
- }
- };
-
- views.put(viewID, transaction);
- fireElementAddedEvent(transaction);
- return transaction;
- }
-
private IView createView(int viewID, CDOProtocolView.Type type)
{
if (type == CDOProtocolView.Type.TRANSACTION)
@@ -202,11 +184,12 @@ public class Session extends Container<IView> implements ISession, CDOIDProvider
/**
* @since 2.0
*/
- public void handleCommitNotification(long timeStamp, List<CDOIDAndVersion> dirtyIDs, List<CDORevisionDelta> deltas)
+ public void handleCommitNotification(long timeStamp, List<CDOIDAndVersion> dirtyIDs, List<CDOID> detachedObjects, List<CDORevisionDelta> deltas)
{
if (!isPassiveUpdateEnabled())
{
dirtyIDs = Collections.emptyList();
+ detachedObjects = Collections.emptyList();
}
// Look if someone needs to know something about modified objects
@@ -225,9 +208,9 @@ public class Session extends Container<IView> implements ISession, CDOIDProvider
}
try
{
- if (!dirtyIDs.isEmpty() || !newDeltas.isEmpty())
+ if (!dirtyIDs.isEmpty() || !newDeltas.isEmpty() || detachedObjects.isEmpty())
{
- new CommitNotificationRequest(protocol.getChannel(), timeStamp, dirtyIDs, newDeltas).send();
+ new CommitNotificationRequest(protocol.getChannel(), timeStamp, dirtyIDs, detachedObjects, newDeltas).send();
}
}
catch (Exception ex)
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java
index ede0345a8d..e3c542b2d1 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java
@@ -12,6 +12,7 @@
**************************************************************************/
package org.eclipse.emf.cdo.internal.server;
+import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDAndVersion;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.internal.server.bundle.OM;
@@ -108,14 +109,14 @@ public class SessionManager extends Container<ISession> implements ISessionManag
/**
* @since 2.0
*/
- public void handleCommitNotification(long timeStamp, List<CDOIDAndVersion> dirtyIDs, List<CDORevisionDelta> deltas,
+ public void handleCommitNotification(long timeStamp, List<CDOIDAndVersion> dirtyIDs, List<CDOID> detachedObjects, List<CDORevisionDelta> deltas,
Session excludedSession)
{
for (Session session : getSessions())
{
if (session != excludedSession)
{
- session.handleCommitNotification(timeStamp, dirtyIDs, deltas);
+ session.handleCommitNotification(timeStamp, dirtyIDs,detachedObjects, deltas);
}
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/StoreAccessor.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/StoreAccessor.java
index 70237dcc4d..375e4fa809 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/StoreAccessor.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/StoreAccessor.java
@@ -8,6 +8,7 @@
* Contributors:
* Eike Stepper - initial API and implementation
* Simon McDuff - http://bugs.eclipse.org/201266
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.internal.server;
@@ -30,13 +31,18 @@ import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
import org.eclipse.net4j.util.lifecycle.Lifecycle;
import org.eclipse.net4j.util.om.trace.ContextTracer;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* @author Eike Stepper
*/
public abstract class StoreAccessor extends Lifecycle implements IStoreAccessor
{
private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, StoreAccessor.class);
-
+
+ private List<CommitContext> commitContexts = new ArrayList<CommitContext>();
+
private Store store;
private Object context;
@@ -95,16 +101,23 @@ public abstract class StoreAccessor extends Lifecycle implements IStoreAccessor
return (InternalCDORevision)revision;
}
- public void commit(CommitContext context)
+ /**
+ * @since 2.0
+ */
+ public void write(CommitContext context)
{
if (TRACER.isEnabled())
{
- TRACER.format("Committing transaction: {0}", getView());
+ TRACER.format("Writing transaction: {0}", getView());
}
-
+
+ commitContexts.add(context);
+
writePackages(context.getNewPackages());
addIDMappings(context);
+
context.applyIDMappings();
+
writeRevisions(context.getNewObjects());
if (store.hasWriteDeltaSupport() && store.getRepository().isSupportingRevisionDeltas())
{
@@ -114,19 +127,40 @@ public abstract class StoreAccessor extends Lifecycle implements IStoreAccessor
{
writeRevisions(context.getDirtyObjects());
}
+
+ detachObjects(context.getDetachedObjects());
}
- public void rollback(CommitContext context)
+ /**
+ * @since 2.0
+ */
+ public void commit()
+ {
+
+ }
+
+ public void rollback(CommitContext commitContext)
+ {
+
+ }
+
+ public void rollback()
{
if (TRACER.isEnabled())
{
TRACER.format("Rolling back transaction: {0}", getView());
}
+
+ for (CommitContext commitContext : commitContexts)
+ {
+ rollback(commitContext);
+ }
}
public final void release()
{
store.releaseAccessor(this);
+ commitContexts.clear();
}
protected void addIDMappings(CommitContext context)
@@ -195,6 +229,17 @@ public abstract class StoreAccessor extends Lifecycle implements IStoreAccessor
}
}
+ /**
+ * @since 2.0
+ */
+ protected void detachObjects(CDOID[] detachedObjects)
+ {
+ for (CDOID id : detachedObjects)
+ {
+ detachObject(id);
+ }
+ }
+
protected void writeRevision(CDORevision revision)
{
throw new UnsupportedOperationException();
@@ -213,13 +258,27 @@ public abstract class StoreAccessor extends Lifecycle implements IStoreAccessor
throw new UnsupportedOperationException();
}
+ /**
+ * @since 2.0
+ */
+ protected void detachObject(CDOID id)
+ {
+ throw new UnsupportedOperationException();
+ }
+
@Override
protected abstract void doActivate() throws Exception;
@Override
protected abstract void doDeactivate() throws Exception;
+ /**
+ * @since 2.0
+ */
protected abstract void doPassivate() throws Exception;
+ /**
+ * @since 2.0
+ */
protected abstract void doUnpassivate() throws Exception;
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Transaction.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Transaction.java
index 817e99266c..bf710086ae 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Transaction.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Transaction.java
@@ -8,440 +8,101 @@
* Contributors:
* Eike Stepper - initial API and implementation
* Simon McDuff - http://bugs.eclipse.org/233490
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.internal.server;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDMetaRange;
-import org.eclipse.emf.cdo.common.id.CDOIDObjectFactory;
-import org.eclipse.emf.cdo.common.id.CDOIDTemp;
import org.eclipse.emf.cdo.common.model.CDOPackage;
-import org.eclipse.emf.cdo.common.model.CDOPackageManager;
-import org.eclipse.emf.cdo.common.model.core.CDOCorePackage;
-import org.eclipse.emf.cdo.common.model.resource.CDOResourcePackage;
import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionResolver;
-import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
-import org.eclipse.emf.cdo.internal.server.bundle.OM;
-import org.eclipse.emf.cdo.server.IPackageManager;
-import org.eclipse.emf.cdo.server.IRepository;
-import org.eclipse.emf.cdo.server.IStoreWriter;
+import org.eclipse.emf.cdo.internal.server.TransactionCommitContextImpl.TransactionPackageManager;
import org.eclipse.emf.cdo.server.ITransaction;
-import org.eclipse.emf.cdo.server.StoreThreadLocal;
-import org.eclipse.emf.cdo.spi.common.InternalCDOPackage;
-import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.common.InternalCDORevisionDelta;
+import org.eclipse.emf.cdo.server.IStoreWriter.CommitContext;
-import org.eclipse.net4j.util.ObjectUtil;
-import org.eclipse.net4j.util.event.IListener;
-import org.eclipse.net4j.util.om.trace.ContextTracer;
-
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
/**
* @author Eike Stepper
+ * @since 2.0
*/
-public class Transaction extends View implements ITransaction, IStoreWriter.CommitContext
+public class Transaction extends View implements ITransaction
{
- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_TRANSACTION, Transaction.class);
-
- private IRepository repository;
-
- private IPackageManager repositoryPackageManager;
-
- private TransactionPackageManager packageManager;
-
- private IStoreWriter storeWriter;
-
- private long timeStamp;
-
- private CDOPackage[] newPackages;
-
- private CDORevision[] newObjects;
-
- private CDORevision[] dirtyObjects;
-
- private CDORevisionDelta[] dirtyObjectDeltas;
-
- private List<CDOIDMetaRange> metaIDRanges = new ArrayList<CDOIDMetaRange>();
-
- private ConcurrentMap<CDOIDTemp, CDOID> idMappings = new ConcurrentHashMap<CDOIDTemp, CDOID>();
-
- private String rollbackMessage;
+ private Repository repository;
public Transaction(Session session, int viewID)
{
super(session, viewID, Type.TRANSACTION);
repository = session.getSessionManager().getRepository();
- repositoryPackageManager = repository.getPackageManager();
- packageManager = new TransactionPackageManager();
- }
-
- public int getTransactionID()
- {
- return getViewID();
- }
-
- public long getTimeStamp()
- {
- return timeStamp;
- }
-
- public TransactionPackageManager getPackageManager()
- {
- return packageManager;
- }
-
- public CDOPackage[] getNewPackages()
- {
- return newPackages;
- }
-
- public CDORevision[] getNewObjects()
- {
- return newObjects;
- }
-
- public CDORevision[] getDirtyObjects()
- {
- return dirtyObjects;
- }
-
- public CDORevisionDelta[] getDirtyObjectDeltas()
- {
- return dirtyObjectDeltas;
- }
-
- public List<CDOIDMetaRange> getMetaIDRanges()
- {
- return Collections.unmodifiableList(metaIDRanges);
- }
-
- public Map<CDOIDTemp, CDOID> getIDMappings()
- {
- return Collections.unmodifiableMap(idMappings);
- }
-
- public void addIDMapping(CDOIDTemp oldID, CDOID newID)
- {
- if (newID == null || newID.isNull() || newID.isTemporary())
- {
- throw new IllegalStateException("newID=" + newID);
- }
-
- CDOID previousMapping = idMappings.putIfAbsent(oldID, newID);
- if (previousMapping != null)
- {
- throw new IllegalStateException("previousMapping != null");
- }
- }
-
- public void applyIDMappings()
- {
- applyIDMappings(newObjects);
- applyIDMappings(dirtyObjects);
- for (CDORevisionDelta dirtyObjectDelta : dirtyObjectDeltas)
- {
- ((InternalCDORevisionDelta)dirtyObjectDelta).adjustReferences(idMappings);
- }
- }
-
- public String getRollbackMessage()
- {
- return rollbackMessage;
- }
-
- public void preCommit()
- {
- // Allocate a store writer
- storeWriter = repository.getStore().getWriter(this);
-
- // Make the store writer available in a ThreadLocal variable
- StoreThreadLocal.setStoreReader(storeWriter);
- }
-
- public void commit(CDOPackage[] newPackages, CDORevision[] newObjects, CDORevisionDelta[] dirtyObjectDeltas)
- {
- timeStamp = createTimeStamp();
- this.newPackages = newPackages;
- this.newObjects = newObjects;
- this.dirtyObjectDeltas = dirtyObjectDeltas;
- dirtyObjects = new CDORevision[dirtyObjectDeltas.length];
-
- try
- {
- adjustMetaRanges();
- adjustTimeStamps();
- computeDirtyObjects(!repository.isSupportingRevisionDeltas());
-
- storeWriter.commit(this);
- updateInfraStructure();
- }
- catch (RuntimeException ex)
- {
- OM.LOG.error(ex);
- String storeClass = repository.getStore().getClass().getSimpleName();
- rollbackMessage = "Rollback in " + storeClass + ": " + ex.getMessage();
- rollback();
- }
- }
-
- protected long createTimeStamp()
- {
- return System.currentTimeMillis();
- }
-
- public void postCommit(boolean success)
- {
- try
- {
- repository.getNotificationManager().notifyCommit(getSession(), this);
- }
- finally
- {
- StoreThreadLocal.release();
- storeWriter = null;
- timeStamp = 0L;
- packageManager.clear();
- metaIDRanges.clear();
- idMappings.clear();
- rollbackMessage = null;
- newPackages = null;
- newObjects = null;
- dirtyObjectDeltas = null;
- dirtyObjects = null;
- }
}
- private void adjustTimeStamps()
- {
- for (CDORevision newObject : newObjects)
- {
- InternalCDORevision revision = (InternalCDORevision)newObject;
- revision.setCreated(timeStamp);
- }
- }
-
- private void adjustMetaRanges()
- {
- for (CDOPackage newPackage : newPackages)
- {
- if (newPackage.getParentURI() == null)
- {
- adjustMetaRange(newPackage);
- }
- }
- }
-
- private void adjustMetaRange(CDOPackage newPackage)
- {
- CDOIDMetaRange oldRange = newPackage.getMetaIDRange();
- if (!oldRange.isTemporary())
- {
- throw new IllegalStateException("!oldRange.isTemporary()");
- }
-
- CDOIDMetaRange newRange = repository.getMetaIDRange(oldRange.size());
- ((InternalCDOPackage)newPackage).setMetaIDRange(newRange);
- for (int l = 0; l < oldRange.size(); l++)
- {
- CDOIDTemp oldID = (CDOIDTemp)oldRange.get(l);
- CDOID newID = newRange.get(l);
- if (TRACER.isEnabled())
- {
- TRACER.format("Mapping meta ID: {0} --> {1}", oldID, newID);
- }
-
- idMappings.put(oldID, newID);
- }
-
- metaIDRanges.add(newRange);
- }
-
- private void computeDirtyObjects(boolean failOnNull)
- {
- for (int i = 0; i < dirtyObjectDeltas.length; i++)
- {
- dirtyObjects[i] = computeDirtyObject(dirtyObjectDeltas[i], failOnNull);
- if (dirtyObjects[i] == null && failOnNull)
- {
- throw new IllegalStateException("Can not retrieve origin revision for " + dirtyObjectDeltas[i]);
- }
- }
- }
-
- private CDORevision computeDirtyObject(CDORevisionDelta dirtyObjectDelta, boolean loadOnDemand)
- {
- CDOID id = dirtyObjectDelta.getID();
- int version = dirtyObjectDelta.getOriginVersion();
-
- CDORevisionResolver revisionResolver = repository.getRevisionManager();
- CDORevision originObject = revisionResolver.getRevisionByVersion(id, CDORevision.UNCHUNKED, version, loadOnDemand);
- if (originObject != null)
- {
- InternalCDORevision dirtyObject = (InternalCDORevision)CDORevisionUtil.copy(originObject);
- dirtyObjectDelta.apply(dirtyObject);
- dirtyObject.setCreated(timeStamp);
- // dirtyObject.setVersion(originObject.getVersion() + 1);
- return dirtyObject;
- }
-
- return null;
- }
-
- private void applyIDMappings(CDORevision[] revisions)
- {
- for (CDORevision revision : revisions)
- {
- if (revision != null)
- {
- InternalCDORevision internal = (InternalCDORevision)revision;
- CDOID newID = idMappings.get(internal.getID());
- if (newID != null)
- {
- internal.setID(newID);
- }
-
- internal.adjustReferences(idMappings);
- }
- }
- }
-
- private void rollback()
+ /**
+ * @since 2.0
+ */
+ public Repository getRepository()
{
- if (storeWriter != null)
- {
- try
- {
- storeWriter.rollback(this);
- }
- catch (RuntimeException ex)
- {
- OM.LOG.warn("Problem while rolling back the transaction", ex);
- }
- }
+ return repository;
}
- private void updateInfraStructure()
+ public int getTransactionID()
{
- try
- {
- addNewPackages();
- addRevisions(newObjects);
- addRevisions(dirtyObjects);
- }
- catch (RuntimeException ex)
- {
- // TODO Rethink this case
- OM.LOG.error("FATAL: Memory infrastructure corrupted after successful commit operation of the store");
- }
+ return getViewID();
}
- private void addNewPackages()
+ /**
+ * @since 2.0
+ */
+ public InternalCommitContext createCommitContext()
{
- PackageManager packageManager = (PackageManager)repository.getPackageManager();
- for (int i = 0; i < newPackages.length; i++)
- {
- CDOPackage cdoPackage = newPackages[i];
- packageManager.addPackage(cdoPackage);
- }
+ return new TransactionCommitContextImpl(this);
}
- private void addRevisions(CDORevision[] revisions)
+ /**
+ * For tests only.
+ *
+ * @since 2.0
+ */
+ public InternalCommitContext createCommitContext(final long timeStamp)
{
- RevisionManager revisionManager = (RevisionManager)repository.getRevisionManager();
- for (CDORevision revision : revisions)
+ return new TransactionCommitContextImpl(this)
{
- if (revision != null)
+ @Override
+ protected long createTimeStamp()
{
- revisionManager.addCachedRevision((InternalCDORevision)revision);
+ return timeStamp;
}
- }
+ };
}
/**
- * @author Eike Stepper
+ * @author Simon McDuff
+ * @since 2.0
*/
- public final class TransactionPackageManager implements CDOPackageManager
+ public interface InternalCommitContext extends CommitContext
{
- private List<CDOPackage> newPackages = new ArrayList<CDOPackage>();
+ public Transaction getTransaction();
- public TransactionPackageManager()
- {
- }
-
- public void addPackage(CDOPackage cdoPackage)
- {
- newPackages.add(cdoPackage);
- }
-
- public void clear()
- {
- newPackages.clear();
- }
+ public TransactionPackageManager getPackageManager();
- public CDOIDObjectFactory getCDOIDObjectFactory()
- {
- return repositoryPackageManager.getCDOIDObjectFactory();
- }
-
- public CDOPackage lookupPackage(String uri)
- {
- for (CDOPackage cdoPackage : newPackages)
- {
- if (ObjectUtil.equals(cdoPackage.getPackageURI(), uri))
- {
- return cdoPackage;
- }
- }
+ public void preCommit();
- return repositoryPackageManager.lookupPackage(uri);
- }
+ public void write();
- public CDOCorePackage getCDOCorePackage()
- {
- return repositoryPackageManager.getCDOCorePackage();
- }
+ public void commit();
- public CDOResourcePackage getCDOResourcePackage()
- {
- return repositoryPackageManager.getCDOResourcePackage();
- }
+ public void postCommit(boolean success);
- public int getPackageCount()
- {
- throw new UnsupportedOperationException();
- }
+ public String getRollbackMessage();
- public CDOPackage[] getPackages()
- {
- throw new UnsupportedOperationException();
- }
+ public List<CDOIDMetaRange> getMetaIDRanges();
- public CDOPackage[] getElements()
- {
- throw new UnsupportedOperationException();
- }
+ public void setNewPackages(CDOPackage[] newPackages);
- public boolean isEmpty()
- {
- throw new UnsupportedOperationException();
- }
+ public void setNewObjects(CDORevision[] newObjects);
- public void addListener(IListener listener)
- {
- throw new UnsupportedOperationException();
- }
+ public void setDirtyObjectDeltas(CDORevisionDelta[] dirtyObjectDeltas);
- public void removeListener(IListener listener)
- {
- throw new UnsupportedOperationException();
- }
+ public void setDetachedObjects(CDOID[] detachedObjects);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContextImpl.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContextImpl.java
new file mode 100644
index 0000000000..ab894380e8
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContextImpl.java
@@ -0,0 +1,527 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.server;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDMetaRange;
+import org.eclipse.emf.cdo.common.id.CDOIDObjectFactory;
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.common.model.CDOPackage;
+import org.eclipse.emf.cdo.common.model.CDOPackageManager;
+import org.eclipse.emf.cdo.common.model.core.CDOCorePackage;
+import org.eclipse.emf.cdo.common.model.resource.CDOResourcePackage;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionResolver;
+import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.internal.server.bundle.OM;
+import org.eclipse.emf.cdo.server.IStoreWriter;
+import org.eclipse.emf.cdo.server.StoreThreadLocal;
+import org.eclipse.emf.cdo.spi.common.InternalCDOPackage;
+import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.InternalCDORevisionDelta;
+
+import org.eclipse.net4j.util.ObjectUtil;
+import org.eclipse.net4j.util.event.IListener;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * @author Simon McDuff
+ * @since 2.0
+ */
+public class TransactionCommitContextImpl implements IStoreWriter.CommitContext, Transaction.InternalCommitContext
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_TRANSACTION,
+ TransactionCommitContextImpl.class);
+
+ private TransactionPackageManager packageManager = new TransactionPackageManager();
+
+ private IStoreWriter storeWriter;
+
+ private long timeStamp;
+
+ private CDOPackage[] newPackages;
+
+ private CDORevision[] newObjects;
+
+ private CDORevision[] dirtyObjects;
+
+ private CDOID[] detachedObjects;
+
+ private List<InternalCDORevision> detachedRevisions = new ArrayList<InternalCDORevision>();;
+
+ private CDORevisionDelta[] dirtyObjectDeltas;
+
+ private List<CDOIDMetaRange> metaIDRanges = new ArrayList<CDOIDMetaRange>();
+
+ private ConcurrentMap<CDOIDTemp, CDOID> idMappings = new ConcurrentHashMap<CDOIDTemp, CDOID>();
+
+ private String rollbackMessage;
+
+ private Transaction transaction;
+
+ public TransactionCommitContextImpl(Transaction transaction)
+ {
+ this.transaction = transaction;
+ }
+
+ public int getTransactionID()
+ {
+ return transaction.getViewID();
+ }
+
+ public Transaction getTransaction()
+ {
+ return transaction;
+ }
+
+ public long getTimeStamp()
+ {
+ return timeStamp;
+ }
+
+ public TransactionPackageManager getPackageManager()
+ {
+ return packageManager;
+ }
+
+ public CDOPackage[] getNewPackages()
+ {
+ return newPackages;
+ }
+
+ public CDORevision[] getNewObjects()
+ {
+ return newObjects;
+ }
+
+ public CDORevision[] getDirtyObjects()
+ {
+ return dirtyObjects;
+ }
+
+ public CDOID[] getDetachedObjects()
+ {
+ return detachedObjects;
+ }
+
+ public CDORevisionDelta[] getDirtyObjectDeltas()
+ {
+ return dirtyObjectDeltas;
+ }
+
+ public List<CDOIDMetaRange> getMetaIDRanges()
+ {
+ return Collections.unmodifiableList(metaIDRanges);
+ }
+
+ public Map<CDOIDTemp, CDOID> getIDMappings()
+ {
+ return Collections.unmodifiableMap(idMappings);
+ }
+
+ public void addIDMapping(CDOIDTemp oldID, CDOID newID)
+ {
+ if (newID == null || newID.isNull() || newID.isTemporary())
+ {
+ throw new IllegalStateException("newID=" + newID);
+ }
+
+ CDOID previousMapping = idMappings.putIfAbsent(oldID, newID);
+ if (previousMapping != null)
+ {
+ throw new IllegalStateException("previousMapping != null");
+ }
+ }
+
+ public void applyIDMappings()
+ {
+ applyIDMappings(newObjects);
+ applyIDMappings(dirtyObjects);
+ for (CDORevisionDelta dirtyObjectDelta : dirtyObjectDeltas)
+ {
+ ((InternalCDORevisionDelta)dirtyObjectDelta).adjustReferences(idMappings);
+ }
+ }
+
+ public String getRollbackMessage()
+ {
+ return rollbackMessage;
+ }
+
+ public void preCommit()
+ {
+ // Allocate a store writer
+ storeWriter = transaction.getRepository().getStore().getWriter(transaction);
+
+ // Make the store writer available in a ThreadLocal variable
+ StoreThreadLocal.setStoreReader(storeWriter);
+ }
+
+ public void setNewPackages(CDOPackage[] newPackages)
+ {
+ this.newPackages = newPackages;
+ }
+
+ public void setNewObjects(CDORevision[] newObjects)
+ {
+ this.newObjects = newObjects;
+ }
+
+ public void setDirtyObjectDeltas(CDORevisionDelta[] dirtyObjectDeltas)
+ {
+ this.dirtyObjectDeltas = dirtyObjectDeltas;
+ }
+
+ public void setDetachedObjects(CDOID[] detachedObjects)
+ {
+ this.detachedObjects = detachedObjects;
+ }
+
+ public void commit()
+ {
+ try
+ {
+ storeWriter.commit();
+ updateInfraStructure();
+ }
+ catch (RuntimeException ex)
+ {
+ handleException(ex);
+ }
+ catch (Error ex)
+ {
+ handleException(ex);
+ }
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void write()
+ {
+ timeStamp = createTimeStamp();
+ dirtyObjects = new CDORevision[dirtyObjectDeltas.length];
+
+ try
+ {
+ adjustMetaRanges();
+ adjustTimeStamps();
+ computeDirtyObjects(!transaction.getRepository().isSupportingRevisionDeltas());
+ detachObjects();
+ storeWriter.write(this);
+ }
+ catch (RuntimeException ex)
+ {
+ handleException(ex);
+ }
+ catch (Error ex)
+ {
+ handleException(ex);
+ }
+ }
+
+ private void handleException(Throwable ex)
+ {
+ OM.LOG.error(ex);
+ String storeClass = transaction.getRepository().getStore().getClass().getSimpleName();
+ rollbackMessage = "Rollback in " + storeClass + ": " + ex.getMessage();
+ rollback();
+ }
+
+ protected long createTimeStamp()
+ {
+ return System.currentTimeMillis();
+ }
+
+ public void postCommit(boolean success)
+ {
+ try
+ {
+ if (success)
+ {
+ transaction.getRepository().getNotificationManager().notifyCommit(transaction.getSession(), this);
+ }
+ }
+ finally
+ {
+ StoreThreadLocal.release();
+ storeWriter = null;
+ timeStamp = 0L;
+ packageManager.clear();
+ metaIDRanges.clear();
+ idMappings.clear();
+ rollbackMessage = null;
+ newPackages = null;
+ newObjects = null;
+ dirtyObjectDeltas = null;
+ dirtyObjects = null;
+ }
+ }
+
+ private void adjustTimeStamps()
+ {
+ for (CDORevision newObject : newObjects)
+ {
+ InternalCDORevision revision = (InternalCDORevision)newObject;
+ revision.setCreated(timeStamp);
+ }
+ }
+
+ private void adjustMetaRanges()
+ {
+ for (CDOPackage newPackage : newPackages)
+ {
+ if (newPackage.getParentURI() == null)
+ {
+ adjustMetaRange(newPackage);
+ }
+ }
+ }
+
+ private void adjustMetaRange(CDOPackage newPackage)
+ {
+ CDOIDMetaRange oldRange = newPackage.getMetaIDRange();
+ if (!oldRange.isTemporary())
+ {
+ throw new IllegalStateException("!oldRange.isTemporary()");
+ }
+
+ CDOIDMetaRange newRange = transaction.getRepository().getMetaIDRange(oldRange.size());
+ ((InternalCDOPackage)newPackage).setMetaIDRange(newRange);
+ for (int l = 0; l < oldRange.size(); l++)
+ {
+ CDOIDTemp oldID = (CDOIDTemp)oldRange.get(l);
+ CDOID newID = newRange.get(l);
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Mapping meta ID: {0} --> {1}", oldID, newID);
+ }
+
+ idMappings.put(oldID, newID);
+ }
+
+ metaIDRanges.add(newRange);
+ }
+
+ private void computeDirtyObjects(boolean failOnNull)
+ {
+ for (int i = 0; i < dirtyObjectDeltas.length; i++)
+ {
+ dirtyObjects[i] = computeDirtyObject(dirtyObjectDeltas[i], failOnNull);
+ if (dirtyObjects[i] == null && failOnNull)
+ {
+ throw new IllegalStateException("Can not retrieve origin revision for " + dirtyObjectDeltas[i]);
+ }
+ }
+ }
+
+ private CDORevision computeDirtyObject(CDORevisionDelta dirtyObjectDelta, boolean loadOnDemand)
+ {
+ CDOID id = dirtyObjectDelta.getID();
+ int version = dirtyObjectDelta.getOriginVersion();
+
+ CDORevisionResolver revisionResolver = transaction.getRepository().getRevisionManager();
+ CDORevision originObject = revisionResolver.getRevisionByVersion(id, CDORevision.UNCHUNKED, version, loadOnDemand);
+ if (originObject != null)
+ {
+ InternalCDORevision dirtyObject = (InternalCDORevision)CDORevisionUtil.copy(originObject);
+ dirtyObjectDelta.apply(dirtyObject);
+ dirtyObject.setCreated(timeStamp);
+ // dirtyObject.setVersion(originObject.getVersion() + 1);
+ return dirtyObject;
+ }
+
+ return null;
+ }
+
+ private void applyIDMappings(CDORevision[] revisions)
+ {
+ for (CDORevision revision : revisions)
+ {
+ if (revision != null)
+ {
+ InternalCDORevision internal = (InternalCDORevision)revision;
+ CDOID newID = idMappings.get(internal.getID());
+ if (newID != null)
+ {
+ internal.setID(newID);
+ }
+
+ internal.adjustReferences(idMappings);
+ }
+ }
+ }
+
+ protected void rollback()
+ {
+ if (storeWriter != null)
+ {
+ try
+ {
+ storeWriter.rollback();
+ }
+ catch (RuntimeException ex)
+ {
+ OM.LOG.warn("Problem while rolling back the transaction", ex);
+ }
+ }
+ }
+
+ private void updateInfraStructure()
+ {
+ try
+ {
+ addNewPackages();
+ addRevisions(newObjects);
+ addRevisions(dirtyObjects);
+ revisedDetachObjects();
+ }
+ catch (RuntimeException ex)
+ {
+ // TODO Rethink this case
+ OM.LOG.error("FATAL: Memory infrastructure corrupted after successful commit operation of the store");
+ }
+ }
+
+ private void addNewPackages()
+ {
+ PackageManager packageManager = transaction.getRepository().getPackageManager();
+ for (int i = 0; i < newPackages.length; i++)
+ {
+ CDOPackage cdoPackage = newPackages[i];
+ packageManager.addPackage(cdoPackage);
+ }
+ }
+
+ private void addRevisions(CDORevision[] revisions)
+ {
+ RevisionManager revisionManager = transaction.getRepository().getRevisionManager();
+ for (CDORevision revision : revisions)
+ {
+ if (revision != null)
+ {
+ revisionManager.addCachedRevision((InternalCDORevision)revision);
+ }
+ }
+ }
+
+ private void revisedDetachObjects()
+ {
+ for (InternalCDORevision revision : detachedRevisions)
+ {
+ revision.setRevised(getTimeStamp() - 1);
+ }
+ }
+
+ private void detachObjects()
+ {
+ detachedRevisions.clear();
+
+ RevisionManager revisionManager = transaction.getRepository().getRevisionManager();
+
+ for (CDOID id : getDetachedObjects())
+ {
+ InternalCDORevision revision = revisionManager.getRevision(id, CDORevision.UNCHUNKED, false);
+ if (revision != null)
+ {
+ detachedRevisions.add(revision);
+ }
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public final class TransactionPackageManager implements CDOPackageManager
+ {
+ private List<CDOPackage> newPackages = new ArrayList<CDOPackage>();
+
+ public TransactionPackageManager()
+ {
+ }
+
+ public void addPackage(CDOPackage cdoPackage)
+ {
+ newPackages.add(cdoPackage);
+ }
+
+ public void clear()
+ {
+ newPackages.clear();
+ }
+
+ public CDOIDObjectFactory getCDOIDObjectFactory()
+ {
+ return transaction.getRepository().getPackageManager().getCDOIDObjectFactory();
+ }
+
+ public CDOPackage lookupPackage(String uri)
+ {
+ for (CDOPackage cdoPackage : newPackages)
+ {
+ if (ObjectUtil.equals(cdoPackage.getPackageURI(), uri))
+ {
+ return cdoPackage;
+ }
+ }
+
+ return transaction.getRepository().getPackageManager().lookupPackage(uri);
+ }
+
+ public CDOCorePackage getCDOCorePackage()
+ {
+ return transaction.getRepository().getPackageManager().getCDOCorePackage();
+ }
+
+ public CDOResourcePackage getCDOResourcePackage()
+ {
+ return transaction.getRepository().getPackageManager().getCDOResourcePackage();
+ }
+
+ public int getPackageCount()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public CDOPackage[] getPackages()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public CDOPackage[] getElements()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isEmpty()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void addListener(IListener listener)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void removeListener(IListener listener)
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/XATransactionCommitContext.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/XATransactionCommitContext.java
new file mode 100644
index 0000000000..2005a1371b
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/XATransactionCommitContext.java
@@ -0,0 +1,122 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.server;
+
+
+import org.eclipse.emf.cdo.internal.server.bundle.OM;
+
+import org.eclipse.net4j.util.WrappedException;
+import org.eclipse.net4j.util.concurrent.ConcurrentValue;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+/**
+ * @author Simon McDuff
+ * @since 2.0
+ */
+public class XATransactionCommitContext extends TransactionCommitContextImpl
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_TRANSACTION, XATransactionCommitContext.class);
+
+ private ConcurrentValue<CommitState> state = new ConcurrentValue<CommitState>(CommitState.STARTING);
+
+ public XATransactionCommitContext(Transaction transaction)
+ {
+ super(transaction);
+ }
+
+ public ConcurrentValue<CommitState> getState()
+ {
+ return state;
+ }
+
+ @Override
+ public void postCommit(boolean success)
+ {
+ getTransaction().getRepository().getCommitManager().remove(this);
+ super.postCommit(success);
+ }
+
+ @Override
+ protected void rollback()
+ {
+ super.rollback();
+
+ // Change the state to unblock call.
+ state.set(CommitState.ROLLED_BACK);
+ }
+
+ /**
+ * Wait until another thread fills ID mapping for external objects.
+ */
+ @Override
+ public void applyIDMappings()
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Notify phase2 to fill ID mapping.");
+ }
+
+ state.set(CommitState.APPLY_ID_MAPPING);
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Waiting for phase2 to be completed before continueing.");
+ }
+
+ try
+ {
+ state.acquire(PHASEAPPLYMAPPING_DONE);
+ }
+ catch (InterruptedException ex)
+ {
+ throw WrappedException.wrap(ex);
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Received signal to continue.");
+ }
+
+ super.applyIDMappings();
+ }
+
+ /**
+ * Object to test if the process is at ApplyIDMapping
+ */
+ final public static Object PHASEAPPLYMAPPING = new Object()
+ {
+ @Override
+ public boolean equals(Object object)
+ {
+ return CommitState.ROLLED_BACK == object || CommitState.APPLY_ID_MAPPING == object;
+ }
+ };
+
+ /**
+ * Object to test if the process did applyIDMapping
+ */
+ final public static Object PHASEAPPLYMAPPING_DONE = new Object()
+ {
+ @Override
+ public boolean equals(Object object)
+ {
+ return CommitState.ROLLED_BACK == object || CommitState.APPLY_ID_MAPPING_DONE == object;
+ }
+ };
+
+ /**
+ * @author Simon McDuff
+ * @since 2.0
+ */
+ public enum CommitState
+ {
+ STARTING, APPLY_ID_MAPPING, APPLY_ID_MAPPING_DONE, ROLLED_BACK
+ };
+}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CDOServerProtocol.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CDOServerProtocol.java
index a685a0a67e..1c430ae951 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CDOServerProtocol.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CDOServerProtocol.java
@@ -10,6 +10,7 @@
* Simon McDuff - http://bugs.eclipse.org/233273
* Simon McDuff - http://bugs.eclipse.org/230832
* Simon McDuff - http://bugs.eclipse.org/233490
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.internal.server.protocol;
@@ -93,6 +94,18 @@ public class CDOServerProtocol extends CDOProtocolImpl
case CDOProtocolConstants.SIGNAL_CHANGE_SUBSCRIPTION:
return new ChangeSubscriptionIndication();
+ case CDOProtocolConstants.SIGNAL_COMMIT_TRANSACTION_PHASE1:
+ return new CommitTransactionPhase1Indication();
+
+ case CDOProtocolConstants.SIGNAL_COMMIT_TRANSACTION_PHASE2:
+ return new CommitTransactionPhase2Indication();
+
+ case CDOProtocolConstants.SIGNAL_COMMIT_TRANSACTION_PHASE3:
+ return new CommitTransactionPhase3Indication();
+
+ case CDOProtocolConstants.SIGNAL_COMMIT_TRANSACTION_CANCEL:
+ return new CommitTransactionCancelIndication();
+
default:
return null;
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitNotificationRequest.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitNotificationRequest.java
index ca45be0269..828005d497 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitNotificationRequest.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitNotificationRequest.java
@@ -14,6 +14,7 @@ package org.eclipse.emf.cdo.internal.server.protocol;
import org.eclipse.emf.cdo.common.CDODataOutput;
import org.eclipse.emf.cdo.common.CDOProtocolConstants;
+import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDAndVersion;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.internal.server.bundle.OM;
@@ -37,14 +38,17 @@ public class CommitNotificationRequest extends CDOServerRequest
private List<CDOIDAndVersion> dirtyIDs;
private List<CDORevisionDelta> deltas;
+
+ private List<CDOID> detachedObjects;
public CommitNotificationRequest(IChannel channel, long timeStamp, List<CDOIDAndVersion> dirtyIDs,
- List<CDORevisionDelta> deltas)
+ List<CDOID> detachedObjects, List<CDORevisionDelta> deltas)
{
super(channel);
this.timeStamp = timeStamp;
this.dirtyIDs = dirtyIDs;
this.deltas = deltas;
+ this.detachedObjects = detachedObjects;
}
@Override
@@ -83,5 +87,11 @@ public class CommitNotificationRequest extends CDOServerRequest
{
out.writeCDORevisionDelta(delta);
}
+
+ out.writeInt(detachedObjects == null ? 0 : detachedObjects.size());
+ for (CDOID id : detachedObjects)
+ {
+ out.writeCDOID(id);
+ }
}
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionCancelIndication.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionCancelIndication.java
new file mode 100644
index 0000000000..2de96d322a
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionCancelIndication.java
@@ -0,0 +1,70 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.server.protocol;
+
+import org.eclipse.emf.cdo.common.CDODataInput;
+import org.eclipse.emf.cdo.common.CDODataOutput;
+import org.eclipse.emf.cdo.common.CDOProtocolConstants;
+
+import java.io.IOException;
+
+/**
+ * @author Simon McDuff
+ */
+public class CommitTransactionCancelIndication extends CommitTransactionIndication
+{
+ public CommitTransactionCancelIndication()
+ {
+ }
+
+ @Override
+ protected short getSignalID()
+ {
+ return CDOProtocolConstants.SIGNAL_COMMIT_TRANSACTION_CANCEL;
+ }
+
+ @Override
+ protected void indicating(CDODataInput in) throws IOException
+ {
+ indicationTransaction(in);
+ }
+
+ @Override
+ protected void responding(CDODataOutput out) throws IOException
+ {
+ String exceptionMessage = null;
+ try
+ {
+ if (commitContext != null)
+ {
+ getRepository().getCommitManager().rollback(commitContext);
+ }
+ }
+ catch (Exception exception)
+ {
+ exceptionMessage = exception.getMessage();
+ }
+
+ if (commitContext != null && exceptionMessage == null)
+ {
+ exceptionMessage = commitContext.getRollbackMessage();
+ }
+
+ respondingException(out, exceptionMessage);
+ }
+
+ @Override
+ protected void indicationTransaction(CDODataInput in) throws IOException
+ {
+ int viewID = in.readInt();
+ commitContext = getRepository().getCommitManager().get(getTransaction(viewID));
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionIndication.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionIndication.java
index 804ddca1e0..38018523f3 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionIndication.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionIndication.java
@@ -8,6 +8,7 @@
* Contributors:
* Eike Stepper - initial API and implementation
* Simon McDuff - http://bugs.eclipse.org/201266
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.internal.server.protocol;
@@ -21,7 +22,8 @@ import org.eclipse.emf.cdo.common.model.CDOPackage;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.internal.server.Transaction;
-import org.eclipse.emf.cdo.internal.server.Transaction.TransactionPackageManager;
+import org.eclipse.emf.cdo.internal.server.Transaction.InternalCommitContext;
+import org.eclipse.emf.cdo.internal.server.TransactionCommitContextImpl.TransactionPackageManager;
import org.eclipse.emf.cdo.internal.server.bundle.OM;
import org.eclipse.emf.cdo.server.IView;
@@ -40,7 +42,7 @@ public class CommitTransactionIndication extends CDOServerIndication
private static final ContextTracer PROTOCOL_TRACER = new ContextTracer(OM.DEBUG_PROTOCOL,
CommitTransactionIndication.class);
- private Transaction transaction;
+ protected InternalCommitContext commitContext;
public CommitTransactionIndication()
{
@@ -52,22 +54,68 @@ public class CommitTransactionIndication extends CDOServerIndication
return CDOProtocolConstants.SIGNAL_COMMIT_TRANSACTION;
}
- @Override
+ @Override
protected TransactionPackageManager getPackageManager()
{
- return transaction.getPackageManager();
+ return commitContext.getPackageManager();
+ }
+ @Override
+ protected void indicating(CDODataInput in) throws IOException
+ {
+ try
+ {
+ indicatingCommit(in);
+ indicatingCommit();
+ }
+ catch (IOException ex)
+ {
+ throw ex;
+ }
+ catch (Exception ex)
+ {
+ OM.LOG.error(ex);
+ }
}
@Override
- protected void indicating(CDODataInput in) throws IOException
+ protected void responding(CDODataOutput out) throws IOException
+ {
+ boolean success = false;
+
+ try
+ {
+ success = respondingException(out, commitContext.getRollbackMessage());
+ if (success)
+ {
+ respondingTimestamp(out);
+ respondingMappingNewPackages(out);
+ respondingMappingNewObjects(out);
+ }
+ }
+ finally
+ {
+ commitContext.postCommit(success);
+ }
+ }
+
+ protected void indicationTransaction(CDODataInput in) throws IOException
{
int viewID = in.readInt();
- transaction = getTransaction(viewID);
- transaction.preCommit();
+ commitContext = getTransaction(viewID).createCommitContext();
+ }
+
+ protected void indicatingCommit(CDODataInput in) throws IOException
+ {
+ // Create transaction context
+ indicationTransaction(in);
+
+ commitContext.preCommit();
+ TransactionPackageManager packageManager = commitContext.getPackageManager();
CDOPackage[] newPackages = new CDOPackage[in.readInt()];
CDORevision[] newObjects = new CDORevision[in.readInt()];
CDORevisionDelta[] dirtyObjectDeltas = new CDORevisionDelta[in.readInt()];
+ CDOID[] detachedObjects = new CDOID[in.readInt()];
// New packages
if (PROTOCOL_TRACER.isEnabled())
@@ -75,7 +123,6 @@ public class CommitTransactionIndication extends CDOServerIndication
PROTOCOL_TRACER.format("Reading {0} new packages", newPackages.length);
}
- TransactionPackageManager packageManager = transaction.getPackageManager();
for (int i = 0; i < newPackages.length; i++)
{
newPackages[i] = in.readCDOPackage();
@@ -104,57 +151,67 @@ public class CommitTransactionIndication extends CDOServerIndication
dirtyObjectDeltas[i] = in.readCDORevisionDelta();
}
- transaction.commit(newPackages, newObjects, dirtyObjectDeltas);
+ for (int i = 0; i < detachedObjects.length; i++)
+ {
+ detachedObjects[i] = in.readCDOID();
+ }
+
+ commitContext.setNewPackages(newPackages);
+ commitContext.setNewObjects(newObjects);
+ commitContext.setDirtyObjectDeltas(dirtyObjectDeltas);
+ commitContext.setDetachedObjects(detachedObjects);
}
- @Override
- protected void responding(CDODataOutput out) throws IOException
+ protected void indicatingCommit()
{
- boolean success = false;
+ commitContext.write();
+ commitContext.commit();
+ }
- try
+ protected boolean respondingException(CDODataOutput out, String rollbackMessage) throws IOException
+ {
+ boolean success = rollbackMessage == null;
+ out.writeBoolean(success);
+ if (!success)
{
- String rollbackMessage = transaction.getRollbackMessage();
- success = rollbackMessage == null;
- out.writeBoolean(success);
- if (success)
- {
- out.writeLong(transaction.getTimeStamp());
-
- // Meta ID ranges
- List<CDOIDMetaRange> metaRanges = transaction.getMetaIDRanges();
- for (CDOIDMetaRange metaRange : metaRanges)
- {
- out.writeCDOIDMetaRange(metaRange);
- }
-
- // ID mappings
- Map<CDOIDTemp, CDOID> idMappings = transaction.getIDMappings();
- for (Entry<CDOIDTemp, CDOID> entry : idMappings.entrySet())
- {
- CDOIDTemp oldID = entry.getKey();
- if (!oldID.isMeta())
- {
- CDOID newID = entry.getValue();
- out.writeCDOID(oldID);
- out.writeCDOID(newID);
- }
- }
+ out.writeString(rollbackMessage);
+ }
+ return success;
+ }
- out.writeCDOID(CDOID.NULL);
- }
- else
- {
- out.writeString(rollbackMessage);
- }
+ protected void respondingTimestamp(CDODataOutput out) throws IOException
+ {
+ out.writeLong(commitContext.getTimeStamp());
+ }
+
+ protected void respondingMappingNewPackages(CDODataOutput out) throws IOException
+ {
+ // Meta ID ranges
+ List<CDOIDMetaRange> metaRanges = commitContext.getMetaIDRanges();
+ for (CDOIDMetaRange metaRange : metaRanges)
+ {
+ out.writeCDOIDMetaRange(metaRange);
}
- finally
+ }
+
+ protected void respondingMappingNewObjects(CDODataOutput out) throws IOException
+ {
+ // ID mappings
+ Map<CDOIDTemp, CDOID> idMappings = commitContext.getIDMappings();
+ for (Entry<CDOIDTemp, CDOID> entry : idMappings.entrySet())
{
- transaction.postCommit(success);
+ CDOIDTemp oldID = entry.getKey();
+ if (!oldID.isMeta())
+ {
+ CDOID newID = entry.getValue();
+ out.writeCDOID(oldID);
+ out.writeCDOID(newID);
+ }
}
+ out.writeCDOID(CDOID.NULL);
}
- private Transaction getTransaction(int viewID)
+ protected Transaction getTransaction(int viewID)
{
IView view = getSession().getView(viewID);
if (view instanceof Transaction)
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionPhase1Indication.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionPhase1Indication.java
new file mode 100644
index 0000000000..9b837e3b77
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionPhase1Indication.java
@@ -0,0 +1,75 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.server.protocol;
+
+import org.eclipse.emf.cdo.common.CDODataInput;
+import org.eclipse.emf.cdo.common.CDODataOutput;
+import org.eclipse.emf.cdo.common.CDOProtocolConstants;
+import org.eclipse.emf.cdo.internal.server.XATransactionCommitContext;
+
+import java.io.IOException;
+
+/**
+ * @author Simon McDuff
+ */
+public class CommitTransactionPhase1Indication extends CommitTransactionIndication
+{
+ public CommitTransactionPhase1Indication()
+ {
+ }
+
+ @Override
+ protected short getSignalID()
+ {
+ return CDOProtocolConstants.SIGNAL_COMMIT_TRANSACTION_PHASE1;
+ }
+
+ @Override
+ protected void indicatingCommit()
+ {
+ // Register transactionContext
+ getRepository().getCommitManager().preCommit(commitContext);
+ }
+
+ @Override
+ protected void responding(CDODataOutput out) throws IOException
+ {
+ String exceptionMessage = null;
+
+ try
+ {
+ ((XATransactionCommitContext)commitContext).getState().acquire(XATransactionCommitContext.PHASEAPPLYMAPPING);
+ }
+ catch (InterruptedException ex)
+ {
+ exceptionMessage = ex.getMessage();
+ }
+
+ if (exceptionMessage == null)
+ {
+ exceptionMessage = commitContext.getRollbackMessage();
+ }
+
+ boolean success = respondingException(out, exceptionMessage);
+ if (success)
+ {
+ respondingTimestamp(out);
+ respondingMappingNewObjects(out);
+ }
+ }
+
+ @Override
+ protected void indicationTransaction(CDODataInput in) throws IOException
+ {
+ int viewID = in.readInt();
+ commitContext = new XATransactionCommitContext(getTransaction(viewID));
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionPhase2Indication.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionPhase2Indication.java
new file mode 100644
index 0000000000..81779ef670
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionPhase2Indication.java
@@ -0,0 +1,101 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.server.protocol;
+
+import org.eclipse.emf.cdo.common.CDODataInput;
+import org.eclipse.emf.cdo.common.CDODataOutput;
+import org.eclipse.emf.cdo.common.CDOProtocolConstants;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.internal.server.XATransactionCommitContext;
+import org.eclipse.emf.cdo.internal.server.XATransactionCommitContext.CommitState;
+import org.eclipse.emf.cdo.internal.server.bundle.OM;
+
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * @author Simon McDuff
+ */
+public class CommitTransactionPhase2Indication extends CommitTransactionIndication
+{
+ private static final ContextTracer PROTOCOL = new ContextTracer(OM.DEBUG_PROTOCOL,
+ CommitTransactionPhase2Indication.class);
+
+ public CommitTransactionPhase2Indication()
+ {
+ }
+
+ @Override
+ protected short getSignalID()
+ {
+ return CDOProtocolConstants.SIGNAL_COMMIT_TRANSACTION_PHASE2;
+ }
+
+ @Override
+ protected void indicating(CDODataInput in) throws IOException
+ {
+ indicationTransaction(in);
+ XATransactionCommitContext xaTransactionContext = (XATransactionCommitContext)commitContext;
+
+ int size = in.readInt();
+ if (PROTOCOL.isEnabled())
+ {
+ PROTOCOL.format("Receiving {0} mapping informations", size);
+ }
+
+ for (int i = 0; i < size; i++)
+ {
+ CDOIDTemp oldID = (CDOIDTemp)in.readCDOID();
+ CDOID newID = in.readCDOID();
+ xaTransactionContext.addIDMapping(oldID, newID);
+ }
+
+ // Mapping information from others CDOTransactions was added. Notify the commit process to continue.
+ xaTransactionContext.getState().set(CommitState.APPLY_ID_MAPPING_DONE);
+ }
+
+ @Override
+ protected void responding(CDODataOutput out) throws IOException
+ {
+ String exceptionMessage = null;
+
+ try
+ {
+ // Return to the client only when the process is ready to commit
+ getRepository().getCommitManager().waitForTermination(commitContext.getTransaction());
+ }
+ catch (InterruptedException ex)
+ {
+ exceptionMessage = ex.getMessage();
+ }
+ catch (ExecutionException ex)
+ {
+ exceptionMessage = ex.getMessage();
+ }
+
+ if (exceptionMessage == null)
+ {
+ exceptionMessage = commitContext.getRollbackMessage();
+ }
+
+ respondingException(out, exceptionMessage);
+ }
+
+ @Override
+ protected void indicationTransaction(CDODataInput in) throws IOException
+ {
+ int viewID = in.readInt();
+ commitContext = getRepository().getCommitManager().get(getTransaction(viewID));
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionPhase3Indication.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionPhase3Indication.java
new file mode 100644
index 0000000000..f7d007074f
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionPhase3Indication.java
@@ -0,0 +1,59 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.server.protocol;
+
+import org.eclipse.emf.cdo.common.CDODataInput;
+import org.eclipse.emf.cdo.common.CDODataOutput;
+import org.eclipse.emf.cdo.common.CDOProtocolConstants;
+
+import java.io.IOException;
+
+/**
+ * @author Simon McDuff
+ */
+public class CommitTransactionPhase3Indication extends CommitTransactionIndication
+{
+ public CommitTransactionPhase3Indication()
+ {
+ }
+
+ @Override
+ protected short getSignalID()
+ {
+ return CDOProtocolConstants.SIGNAL_COMMIT_TRANSACTION_PHASE3;
+ }
+
+ @Override
+ protected void indicating(CDODataInput in) throws IOException
+ {
+ indicationTransaction(in);
+ }
+
+ @Override
+ protected void responding(CDODataOutput out) throws IOException
+ {
+ commitContext.commit();
+ boolean success = respondingException(out, commitContext.getRollbackMessage());
+ if (success)
+ {
+ respondingMappingNewPackages(out);
+ }
+
+ commitContext.postCommit(success);
+ }
+
+ @Override
+ protected void indicationTransaction(CDODataInput in) throws IOException
+ {
+ int viewID = in.readInt();
+ commitContext = getRepository().getCommitManager().get(getTransaction(viewID));
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/INotificationManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/INotificationManager.java
index 13c854fcc5..4eae1f5d8f 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/INotificationManager.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/INotificationManager.java
@@ -18,7 +18,7 @@ import org.eclipse.emf.cdo.server.IStoreWriter.CommitContext;
* @author Simon McDuff
* @since 2.0
*/
-public interface INotificationManager
+public interface INotificationManager extends IRepositoryElement
{
public void notifyCommit(Session session, CommitContext commitContext);
}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStore.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStore.java
index 6831526a3e..8362b40b54 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStore.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStore.java
@@ -61,7 +61,7 @@ public interface IStore extends IRepositoryElement
/**
* Returns if this store supports the storage of concurrent newRevisions in separate branches.
* <p>
- * Note: This is reserved for future use by the framework. There is currently no support for branching in the
+ * <b>Note:</b> This is reserved for future use by the framework. There is currently no support for branching in the
* framework!
*
* @return <code>true</code> if this store supports the storage of concurrent newRevisions in separate branches,
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreWriter.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreWriter.java
index 39e820722c..8fe30bea20 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreWriter.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreWriter.java
@@ -8,6 +8,7 @@
* Contributors:
* Eike Stepper - initial API and implementation
* Simon McDuff - http://bugs.eclipse.org/201266
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.server;
@@ -27,9 +28,22 @@ public interface IStoreWriter extends IStoreReader
{
public IView getView();
- public void commit(CommitContext context);
+ /**
+ * Called before committing. An Instance of a storeWriter represents an instance of back-end Transaction. Could be called multiple times before commit it called.
+ * @since 2.0
+ */
+ public void write(CommitContext context);
- public void rollback(CommitContext context);
+ /**
+ * It will flush to the backend and make available the data for others.
+ * @since 2.0
+ */
+ public void commit();
+
+ /**
+ * @since 2.0
+ */
+ public void rollback();
/**
* Represents the state of a single, logical commit operation which is driven through multiple calls to several
@@ -84,6 +98,14 @@ public interface IStoreWriter extends IStoreReader
public CDORevisionDelta[] getDirtyObjectDeltas();
/**
+ * Returns an array of the removed object that are part of the commit operation represented by this
+ * <code>CommitContext</code>.
+ *
+ * @since 2.0
+ */
+ public CDOID[] getDetachedObjects();
+
+ /**
* Returns an unmodifiable map from all temporary IDs (meta or not) to their persistent counter parts. It is
* initially populated with the mappings of all new meta objects.
*/
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ITransaction.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ITransaction.java
index d115a31400..28cf794d7e 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ITransaction.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ITransaction.java
@@ -7,11 +7,11 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.server;
import org.eclipse.emf.cdo.common.CDOProtocolView;
-import org.eclipse.emf.cdo.common.model.CDOPackageManager;
/**
* @author Eike Stepper
@@ -23,14 +23,4 @@ public interface ITransaction extends IView
* Returns the ID of this transactional view. Same as {@link CDOProtocolView#getViewID() getViewID()}.
*/
public int getTransactionID();
-
- /**
- * Returns the temporary, transactional package manager associated with this ITransaction during the process of a
- * commit operation. In addition to the packages registered with the session {@link IRepository#getPackageManager()
- * package manager} this package manager also contains the new packages that are part of the commit operation.
- *
- * @return a temporary, transactional package manager if this ITransaction is in the process of a commit operation,
- * <code>null</code> otherwise.
- */
- public CDOPackageManager getPackageManager();
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractCDOTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractCDOTest.java
index 0398f97304..b5160b138a 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractCDOTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AbstractCDOTest.java
@@ -142,7 +142,8 @@ public abstract class AbstractCDOTest extends AbstractTransportTest
// assertEquals(null, object.cdoID());
// assertEquals(null, object.cdoRevision());
// assertEquals(null, object.cdoView());
- assertEquals(object.eResource(), object.cdoResource());
+ //assertEquals(bject.eResource(), object.cdoResource());
+ //assertEquals(null, object.cdoResource());
}
protected static void assertNotTransient(CDOObject object, CDOView view)
@@ -151,9 +152,9 @@ public abstract class AbstractCDOTest extends AbstractTransportTest
assertNotNull(object.cdoID());
assertNotNull(object.cdoRevision());
assertNotNull(object.cdoView());
- assertNotNull(object.cdoResource());
+ //assertNotNull(object.cdoResource());
assertNotNull(object.eResource());
- assertEquals(object.eResource(), object.cdoResource());
+ //assertEquals(object.eResource(), object.cdoResource());
assertEquals(view, object.cdoView());
assertEquals(object, view.getObject(object.cdoID(), false));
}
@@ -190,10 +191,10 @@ public abstract class AbstractCDOTest extends AbstractTransportTest
protected static void assertContent(CDOObject container, CDOObject contained)
{
assertEquals(container.eResource(), contained.eResource());
- assertEquals(container.cdoResource(), contained.cdoResource());
assertTrue(container.eContents().contains(contained));
if (container instanceof CDOResource)
{
+ assertEquals(container.eResource(), container.cdoResource());
assertEquals(null, contained.eContainer());
assertTrue(((CDOResource)container).getContents().contains(contained));
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTests.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTests.java
index c6631ef5ce..738628412b 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTests.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTests.java
@@ -12,6 +12,7 @@ package org.eclipse.emf.cdo.tests;
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_241464_Test;
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_243310_Test;
+import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_246622_Test;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -27,6 +28,7 @@ public class AllTests
// $JUnit-BEGIN$
suite.addTestSuite(InitialTest.class);
+
suite.addTestSuite(ComplexTest.class);
suite.addTestSuite(AttributeTest.class);
suite.addTestSuite(EnumTest.class);
@@ -49,9 +51,13 @@ public class AllTests
suite.addTestSuite(NoLegacyTest.class);
suite.addTestSuite(Bugzilla_241464_Test.class);
suite.addTestSuite(Bugzilla_243310_Test.class);
+ suite.addTestSuite(Bugzilla_246622_Test.class);
suite.addTestSuite(AutoAttacherTest.class);
suite.addTestSuite(SavepointTest.class);
suite.addTestSuite(ChangeSubscriptionTest.class);
+ suite.addTestSuite(DetachTest.class);
+ suite.addTestSuite(ExternalReferenceTest.class);
+ suite.addTestSuite(XATransactionTest.class);
// Specific for MEMStore
suite.addTestSuite(QueryTest.class);
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AutoAttacherTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AutoAttacherTest.java
index c7ec73619e..b869e12b9f 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AutoAttacherTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AutoAttacherTest.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
**************************************************************************/
package org.eclipse.emf.cdo.tests;
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ComplexTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ComplexTest.java
index 7c04ca19d6..39f49bb0c8 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ComplexTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ComplexTest.java
@@ -50,6 +50,9 @@ import org.eclipse.emf.cdo.tests.model4interfaces.model4interfacesPackage;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* @author Eike Stepper
*/
@@ -509,10 +512,14 @@ public class ComplexTest extends AbstractCDOTest
CDOTransaction transaction3 = session.openTransaction();
EList<EObject> elements = transaction3.getResource(resource1path).getContents();
EList<EObject> containers = transaction3.getResource(resource2path).getContents();
-
- RefMultiContained container_work = (RefMultiContained)containers.get(0);
+ List<EObject> elementToRemove = new ArrayList<EObject>();
for (EObject o : elements)
{
+ elementToRemove.add(o);
+ }
+ RefMultiContained container_work = (RefMultiContained)containers.get(0);
+ for (EObject o : elementToRemove)
+ {
MultiContainedElement element_work = (MultiContainedElement)o;
container_work.getElements().add(element_work);
transaction3.commit();
@@ -553,13 +560,24 @@ public class ComplexTest extends AbstractCDOTest
resource2.getContents().add(container);
transaction2.commit();
-
- EList<EObject> elements = transaction2.getResource(resource1path).getContents();
-
+ CDOResource resource1FromTx2 = transaction2.getResource(resource1path);
+ EList<EObject> elements = resource1FromTx2.getContents();
+ List<EObject> elementToRemove = new ArrayList<EObject>();
for (EObject o : elements)
{
+ elementToRemove.add(o);
+ }
+
+ for (EObject o : elementToRemove)
+ {
MultiContainedElement element_work = (MultiContainedElement)o;
+ assertEquals(resource1FromTx2, element_work.cdoResource());
+ assertEquals(resource1FromTx2, element_work.eResource());
+
container.getElements().add(element_work);
+
+ assertEquals(null, element_work.cdoResource());
+ assertEquals(resource2, element_work.eResource());
transaction2.commit();
}
}
@@ -582,7 +600,7 @@ public class ComplexTest extends AbstractCDOTest
assertTrue(element.getParent() == container2);
assertTrue(element.eContainer() == container2);
- assertTrue(element.cdoResource() == resource2);
+ assertTrue(element.cdoResource() == null);
assertTrue(container1.getElement() == null);
assertTrue(container1.cdoResource() == resource1);
@@ -614,11 +632,13 @@ public class ComplexTest extends AbstractCDOTest
assertTrue(elementA.getParent() == container2);
assertTrue(elementA.eContainer() == container2);
- assertTrue(elementA.cdoResource() == resource2);
+ assertTrue(elementA.cdoResource() == null);
+ assertTrue(elementA.eResource() == resource2);
assertTrue(elementB.getParent() == container1);
assertTrue(elementB.eContainer() == container1);
- assertTrue(elementB.cdoResource() == resource1);
+ assertTrue(elementB.cdoResource() == null);
+ assertTrue(elementB.eResource() == resource1);
assertTrue(container1.cdoResource() == resource1);
assertEquals(1, container1.getElements().size());
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ContainmentTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ContainmentTest.java
index be37769fa6..eb5203a9d2 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ContainmentTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ContainmentTest.java
@@ -17,12 +17,26 @@ import org.eclipse.emf.cdo.tests.model1.Address;
import org.eclipse.emf.cdo.tests.model1.Category;
import org.eclipse.emf.cdo.tests.model1.Company;
import org.eclipse.emf.cdo.tests.model1.Model1Factory;
+import org.eclipse.emf.cdo.tests.model1.Model1Package;
+import org.eclipse.emf.cdo.tests.model1.Order;
import org.eclipse.emf.cdo.tests.model1.Supplier;
import org.eclipse.emf.cdo.tests.model2.Model2Factory;
import org.eclipse.emf.cdo.tests.model2.SpecialPurchaseOrder;
import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EcoreFactory;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
/**
* @author Eike Stepper
@@ -325,4 +339,142 @@ public class ContainmentTest extends AbstractCDOTest
assertContent(resource, order);
assertNull(order.getShippingAddress());
}
+
+ public void testObjectNotSameResourceThanItsContainer() throws Exception
+ {
+ {
+ ResourceSet resourceSet = new ResourceSetImpl();
+
+ CDOSession session = openSession();
+
+ CDOTransaction transaction = session.openTransaction(resourceSet);
+
+ resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put("file", new XMIResourceFactoryImpl());
+
+ session.getPackageRegistry().putEPackage(Model1Package.eINSTANCE);
+ Resource resource1 = resourceSet.createResource(URI.createFileURI("c:\\1.xml"));
+ Resource resource2 = transaction.createResource("test");
+
+ EPackage packageObject = createDynamicEPackage();
+ EClass eClass = (EClass)packageObject.getEClassifier("SchoolBook");
+
+ EObject container = packageObject.getEFactoryInstance().create(eClass);
+ Order contained = Model1Factory.eINSTANCE.createOrder();
+
+ resource1.getContents().add(container);
+ resource2.getContents().add(contained);
+
+ container.eSet(container.eClass().getEStructuralFeature("proxyElement"), contained);
+
+ assertEquals(resource1, container.eResource());
+ assertEquals(resource2, contained.eResource());
+
+ // If the relationship is define has resolveProxy this is true if not.. this is false.
+ assertEquals(container, contained.eContainer());
+
+ resource1.save(null);
+ transaction.commit();
+ }
+ {
+ EPackage packageObject = createDynamicEPackage();
+ ResourceSet resourceSet = new ResourceSetImpl();
+ resourceSet.getPackageRegistry().put(packageObject.getNsURI(), packageObject);
+ CDOSession session = openSession();
+
+ CDOTransaction transaction = session.openTransaction(resourceSet);
+
+ resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put("file", new XMIResourceFactoryImpl());
+
+ Resource resource = transaction.getResource("test");
+
+ Order order = (Order)resource.getContents().get(0);
+
+ Resource resourceXMI = resourceSet.getResource(URI.createFileURI("c:\\1.xml"), true);
+
+ assertEquals(resourceXMI.getContents().get(0), order.eContainer());
+ }
+
+ }
+
+ public void testObjectNotSameResourceThanItsContainer_WithoutCDO() throws Exception
+ {
+ ResourceSet resourceSet = new ResourceSetImpl();
+
+ resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put("file", new XMIResourceFactoryImpl());
+
+ Resource resource1 = resourceSet.createResource(URI.createFileURI("c:\\1.xml"));
+ Resource resource2 = resourceSet.createResource(URI.createFileURI("c:\\2.xml"));
+ EPackage packageObject = createDynamicEPackage();
+ EClass eClass = (EClass)packageObject.getEClassifier("SchoolBook");
+
+ EObject container = packageObject.getEFactoryInstance().create(eClass);
+ EObject contained = packageObject.getEFactoryInstance().create(eClass);
+
+ resource1.getContents().add(container);
+ resource2.getContents().add(contained);
+
+ container.eSet(container.eClass().getEStructuralFeature("proxyElement"), contained);
+ // resource1.getContents().add(container);
+
+ assertEquals(resource1, container.eResource());
+ assertEquals(resource2, contained.eResource());
+
+ // If the relationship is define has resolveProxy this is true if not.. this is false.
+ assertEquals(container, contained.eContainer());
+ }
+
+ // Do not support legacy system
+ public void _testBug246540() throws Exception
+ {
+ CDOSession session = openModel1Session();
+ CDOTransaction transaction = session.openTransaction();
+
+ CDOResource resource = transaction.createResource("/my/resource1");
+
+ for (EClassifier eClassifier : EcorePackage.eINSTANCE.getEClassifiers())
+ {
+ resource.getContents().add(eClassifier);
+ }
+
+ transaction.commit();
+ session.close();
+ }
+
+ private EPackage createDynamicEPackage()
+ {
+ final EcoreFactory efactory = EcoreFactory.eINSTANCE;
+ final EcorePackage epackage = EcorePackage.eINSTANCE;
+
+ EClass schoolBookEClass = efactory.createEClass();
+ schoolBookEClass.setName("SchoolBook");
+
+ // create a new attribute for this EClass
+ EAttribute level = efactory.createEAttribute();
+ level.setName("level");
+ level.setEType(epackage.getEInt());
+ schoolBookEClass.getEStructuralFeatures().add(level);
+
+ EReference proxyElement = efactory.createEReference();
+ proxyElement.setName("proxyElement");
+ proxyElement.setEType(epackage.getEObject());
+ proxyElement.setResolveProxies(true);
+ proxyElement.setContainment(true);
+ schoolBookEClass.getEStructuralFeatures().add(proxyElement);
+
+ EReference element = efactory.createEReference();
+ element.setName("element");
+ element.setEType(epackage.getEObject());
+ element.setContainment(true);
+ element.setResolveProxies(false);
+ schoolBookEClass.getEStructuralFeatures().add(element);
+
+ // Create a new EPackage and add the new EClasses
+ EPackage schoolPackage = efactory.createEPackage();
+ schoolPackage.setName("elv");
+ schoolPackage.setNsPrefix("elv");
+ schoolPackage.setNsURI("http:///www.elver.org/School");
+ schoolPackage.getEClassifiers().add(schoolBookEClass);
+ return schoolPackage;
+
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/DetachTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/DetachTest.java
new file mode 100644
index 0000000000..c3e9c21399
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/DetachTest.java
@@ -0,0 +1,274 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo.tests;
+
+import org.eclipse.emf.cdo.CDOSavepoint;
+import org.eclipse.emf.cdo.CDOSession;
+import org.eclipse.emf.cdo.CDOTransaction;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.tests.model1.Company;
+import org.eclipse.emf.cdo.tests.model1.Model1Factory;
+import org.eclipse.emf.cdo.tests.model1.Order;
+import org.eclipse.emf.cdo.tests.model1.OrderDetail;
+import org.eclipse.emf.cdo.util.CDOUtil;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+
+import junit.framework.Assert;
+
+/**
+ * @author Simon McDuff
+ */
+public class DetachTest extends AbstractCDOTest
+{
+ public void testNewObjectDeletion() throws Exception
+ {
+ CDOSession session = openModel1Session();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.createResource("/my/resource");
+
+ Company c1 = Model1Factory.eINSTANCE.createCompany();
+ c1.setName("Test");
+ resource.getContents().add(c1);
+
+ final URI uriC1 = EcoreUtil.getURI(c1);
+
+ assertEquals(c1, transaction.getResourceSet().getEObject(uriC1, false));
+
+ resource.getContents().remove(0); // remove object by index
+
+ try
+ {
+ transaction.getResourceSet().getEObject(uriC1, false);
+ fail("Object shouldn't be available anymore");
+ }
+ catch (Exception ex)
+ {
+
+ }
+
+ transaction.commit();
+ }
+
+ public void testCleanObjectDeletion() throws Exception
+ {
+ CDOSession session = openModel1Session();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.createResource("/my/resource");
+
+ Company c1 = Model1Factory.eINSTANCE.createCompany();
+ c1.setName("Test");
+ resource.getContents().add(c1);
+ transaction.commit(); // (1)
+
+ final URI uriC1 = EcoreUtil.getURI(c1);
+
+ assertEquals(c1, transaction.getResourceSet().getEObject(uriC1, false));
+
+ resource.getContents().remove(c1);
+
+ assertTransient(c1);
+
+ // We should not be able to access that objects
+ try
+ {
+ transaction.getResourceSet().getEObject(uriC1, false);
+ fail("Cannot access objects detach");
+ }
+ catch (Exception excp)
+ {
+
+ }
+
+ transaction.commit();
+
+ assertTransient(c1);
+
+ try
+ {
+ transaction.getResourceSet().getEObject(uriC1, false);
+ fail("Cannot access objects detach");
+ }
+ catch (Exception excp)
+ {
+
+ }
+
+
+ }
+
+ public void testSavePointNewObjectDeletion() throws Exception
+ {
+ CDOSession session = openModel1Session();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.createResource("/my/resource");
+
+ Company c1 = Model1Factory.eINSTANCE.createCompany();
+ c1.setName("Test");
+ resource.getContents().add(c1);
+
+ testSavePointObjectDeletion(transaction, resource);
+ }
+
+ public void testSavePointCleanObjectDeletion() throws Exception
+ {
+ CDOSession session = openModel1Session();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.createResource("/my/resource");
+
+ Company c1 = Model1Factory.eINSTANCE.createCompany();
+ c1.setName("Test");
+ resource.getContents().add(c1);
+
+ URI uriC1 = EcoreUtil.getURI(c1);
+
+ assertEquals(c1, transaction.getResourceSet().getEObject(uriC1, false));
+
+ transaction.commit();
+
+ testSavePointObjectDeletion(transaction, resource);
+
+ }
+
+ private void testSavePointObjectDeletion(CDOTransaction transaction, CDOResource resource)
+ {
+ Company c1 = (Company)resource.getContents().get(0);
+
+ URI uriC1 = EcoreUtil.getURI(c1);
+
+ c1.setName("SIMON");
+
+ CDOSavepoint savepoint = transaction.setSavepoint();
+
+ resource.getContents().remove(0); // remove object by index
+
+ CDOSavepoint savepoint2 = transaction.setSavepoint();
+ try
+ {
+ transaction.getResourceSet().getEObject(uriC1, false);
+ fail("Object shouldn't be available anymore");
+ }
+ catch (Exception ex)
+ {
+
+ }
+ savepoint2.rollback();
+
+ assertEquals("SIMON", c1.getName());
+
+ try
+ {
+ transaction.getResourceSet().getEObject(uriC1, false);
+ fail("Object shouldn't be available anymore");
+ }
+ catch (Exception ex)
+ {
+
+ }
+
+ savepoint.rollback();
+
+ assertEquals("SIMON", c1.getName());
+ assertEquals(c1, transaction.getResourceSet().getEObject(uriC1, false));
+
+ transaction.commit();
+ }
+
+ public void testKeepValue() throws Exception
+ {
+ {
+ CDOSession session = openModel1Session();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.createResource("/my/resource");
+
+ Company c1 = Model1Factory.eINSTANCE.createCompany();
+ c1.setName("Test");
+ resource.getContents().add(c1);
+
+ transaction.commit();
+ }
+
+ CDOSession session = openModel1Session();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.getOrCreateResource("/my/resource");
+
+ Company c1 = (Company)resource.getContents().get(0); // remove object by index
+
+ assertEquals("Test", c1.getName());
+
+ resource.getContents().remove(0);
+
+ assertEquals("Test", c1.getName());
+
+ transaction.commit();
+
+ assertEquals("Test", c1.getName());
+ }
+
+ private void detachResource(ResourceSet rset, CDOResource resource) throws Exception
+ {
+ Order order = Model1Factory.eINSTANCE.createOrder();
+ OrderDetail orderDetail = Model1Factory.eINSTANCE.createOrderDetail();
+ resource.getContents().add(order);
+ order.getOrderDetails().add(orderDetail);
+
+ assertActive(resource);
+ Assert.assertEquals(1, CDOUtil.getViewSet(rset).getViews().length);
+ Assert.assertEquals(1, rset.getResources().size());
+
+ resource.delete(null);
+
+ assertTransient(resource);
+
+ Assert.assertEquals(1, CDOUtil.getViewSet(rset).getViews().length);
+ Assert.assertEquals(0, rset.getResources().size());
+ }
+
+ public void testDetachNewResource() throws Exception
+ {
+ msg("Opening session");
+ CDOSession session = openModel1Session();
+
+ msg("Opening transaction");
+ CDOTransaction transaction = session.openTransaction();
+
+ ResourceSet rset = transaction.getResourceSet();
+
+ msg("Creating resource");
+ CDOResource resource = transaction.createResource("/test1");
+ detachResource(rset, resource);
+
+ }
+
+ public void testDetachPersistedResource() throws Exception
+ {
+ msg("Opening session");
+ CDOSession session = openModel1Session();
+
+ msg("Opening transaction");
+ CDOTransaction transaction = session.openTransaction();
+
+ ResourceSet rset = transaction.getResourceSet();
+
+ msg("Creating resource");
+ CDOResource resource = transaction.createResource("/test1");
+
+ transaction.commit();
+ CDOID resourceID = resource.cdoID();
+ detachResource(rset, resource);
+
+ assertEquals(true, transaction.getDetachedObjects().contains(resourceID));
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ExternalReferenceTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ExternalReferenceTest.java
new file mode 100644
index 0000000000..641bd7421e
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ExternalReferenceTest.java
@@ -0,0 +1,334 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo.tests;
+
+import org.eclipse.emf.cdo.CDOSession;
+import org.eclipse.emf.cdo.CDOTransaction;
+import org.eclipse.emf.cdo.CDOViewSet;
+import org.eclipse.emf.cdo.CDOXATransaction;
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.tests.model1.Company;
+import org.eclipse.emf.cdo.tests.model1.Model1Factory;
+import org.eclipse.emf.cdo.tests.model1.Model1Package;
+import org.eclipse.emf.cdo.tests.model1.PurchaseOrder;
+import org.eclipse.emf.cdo.tests.model1.Supplier;
+import org.eclipse.emf.cdo.tests.model2.Model2Package;
+import org.eclipse.emf.cdo.tests.model4.GenRefSingleNonContained;
+import org.eclipse.emf.cdo.tests.model4.model4Factory;
+import org.eclipse.emf.cdo.tests.model4.model4Package;
+import org.eclipse.emf.cdo.util.CDOUtil;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EcoreFactory;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
+
+/**
+ * @author Simon McDuff
+ */
+public class ExternalReferenceTest extends AbstractCDOTest
+{
+ final static public String REPOSITORY2_NAME = "repo2";
+
+
+ public void testExternalWithDynamicEObject() throws Exception
+ {
+ {
+ CDOSession sessionA = openSession();
+
+ ResourceSet resourceSet = new ResourceSetImpl();
+ resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put("file", new XMIResourceFactoryImpl());
+
+ EPackage schoolPackage = createDynamicEPackage();
+ EClass classifier = (EClass)schoolPackage.getEClassifier("SchoolBook");
+
+ EObject schoolbook = schoolPackage.getEFactoryInstance().create(classifier);
+ sessionA.getPackageRegistry().putEPackage(model4Package.eINSTANCE);
+ CDOTransaction transactionA1 = sessionA.openTransaction(resourceSet);
+
+ CDOResource resA = transactionA1.createResource("/resA");
+ Resource resD = resourceSet.createResource(URI.createFileURI("c:\\1.xml"));
+
+ GenRefSingleNonContained objectFromResA = model4Factory.eINSTANCE.createGenRefSingleNonContained();
+ objectFromResA.setElement(schoolbook);
+ resD.getContents().add(schoolbook);
+
+ resA.getContents().add(objectFromResA);
+
+ transactionA1.commit();
+ }
+ }
+
+ public void testExternalWithEClass() throws Exception
+ {
+ {
+ CDOSession sessionA = openSession();
+
+ ResourceSet resourceSet = new ResourceSetImpl();
+
+ sessionA.getPackageRegistry().putEPackage(model4Package.eINSTANCE);
+
+ CDOTransaction transactionA1 = sessionA.openTransaction(resourceSet);
+ CDOResource resA = transactionA1.createResource("/resA");
+ GenRefSingleNonContained objectFromResA = model4Factory.eINSTANCE.createGenRefSingleNonContained();
+ objectFromResA.setElement(Model1Package.eINSTANCE.getAddress());
+ resA.getContents().add(objectFromResA);
+ transactionA1.commit();
+ }
+
+ {
+ CDOSession sessionA = openSession();
+
+ ResourceSet resourceSet = new ResourceSetImpl();
+ resourceSet.getPackageRegistry().put(Model1Package.eINSTANCE.getNsURI(), Model1Package.eINSTANCE);
+
+ CDOTransaction transactionA1 = sessionA.openTransaction(resourceSet);
+ CDOResource resA = transactionA1.getResource("/resA");
+
+ GenRefSingleNonContained objectFromResA = (GenRefSingleNonContained)resA.getContents().get(0);
+ assertEquals(Model1Package.eINSTANCE.getAddress(), objectFromResA.getElement());
+ transactionA1.commit();
+ }
+ }
+ public void testExternalWithEPackage() throws Exception
+ {
+ {
+ CDOSession sessionA = openSession();
+
+ ResourceSet resourceSet = new ResourceSetImpl();
+
+ sessionA.getPackageRegistry().putEPackage(model4Package.eINSTANCE);
+
+ CDOTransaction transactionA1 = sessionA.openTransaction(resourceSet);
+ CDOResource resA = transactionA1.createResource("/resA");
+ GenRefSingleNonContained objectFromResA = model4Factory.eINSTANCE.createGenRefSingleNonContained();
+ objectFromResA.setElement(Model1Package.eINSTANCE);
+ resA.getContents().add(objectFromResA);
+ transactionA1.commit();
+ }
+
+ {
+ CDOSession sessionA = openSession();
+
+ ResourceSet resourceSet = new ResourceSetImpl();
+ resourceSet.getPackageRegistry().put(Model1Package.eINSTANCE.getNsURI(), Model1Package.eINSTANCE);
+
+ CDOTransaction transactionA1 = sessionA.openTransaction(resourceSet);
+ CDOResource resA = transactionA1.getResource("/resA");
+
+ GenRefSingleNonContained objectFromResA = (GenRefSingleNonContained)resA.getContents().get(0);
+ assertEquals(Model1Package.eINSTANCE, objectFromResA.getElement());
+ transactionA1.commit();
+ }
+ }
+
+ public void testOneXMIResourceManyViewsOnOneResourceSet() throws Exception
+ {
+ URI a = URI.createURI("file:/c:/temp");
+ URI b = URI.createURI("file://c:/temp");
+ URI c = URI.createURI("file:///c:/temp");
+
+ System.out.println(a.authority());
+ System.out.println(b.authority());
+ System.out.println(c.authority());
+
+ createRepository(REPOSITORY2_NAME);
+ {
+ CDOSession sessionA = openSession();
+ CDOSession sessionB = openSession(REPOSITORY2_NAME);
+ ResourceSet resourceSet = new ResourceSetImpl();
+ resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put("file", new XMIResourceFactoryImpl());
+
+ sessionA.getPackageRegistry().putEPackage(Model1Package.eINSTANCE);
+ sessionA.getPackageRegistry().putEPackage(Model2Package.eINSTANCE);
+ sessionB.getPackageRegistry().putEPackage(Model1Package.eINSTANCE);
+ sessionB.getPackageRegistry().putEPackage(Model2Package.eINSTANCE);
+
+ CDOTransaction transactionA1 = sessionA.openTransaction(resourceSet);
+ CDOTransaction transactionB1 = sessionB.openTransaction(resourceSet);
+
+ CDOResource resA = transactionA1.createResource("/resA");
+ CDOResource resB = transactionB1.createResource("/resB");
+
+ assertEquals(2, resourceSet.getResources().size());
+ // assertEquals(resA, resourceSet.getResource(CDOUtil.createResourceURI(sessionA, "/resA"), false));
+ // assertEquals(resB, resourceSet.getResource(CDOUtil.createResourceURI(sessionA, "/resB"), false));
+
+ // CDOResource resC = (CDOResource)resourceSet.createResource(CDOUtil.createResourceURI(sessionA, "/resC"));
+ // assertEquals(transactionA1, resC.cdoView());
+ CDOResource resC = transactionA1.createResource("/resC");
+ assertNotNull(resC);
+
+ assertEquals(3, resourceSet.getResources().size());
+ // assertEquals(resC, resourceSet.getResource(CDOUtil.createResourceURI(sessionA, "/resC"), false));
+
+ Resource resD = resourceSet.createResource(URI.createFileURI("c:\\1.xml"));
+
+ assertEquals(4, resourceSet.getResources().size());
+ assertEquals(false, resD instanceof CDOResource);
+
+ Company companyA = Model1Factory.eINSTANCE.createCompany();
+ companyA.setName("VALUEA");
+
+ Company companyB = Model1Factory.eINSTANCE.createCompany();
+ companyB.setName("VALUEB");
+
+ Company companyD = Model1Factory.eINSTANCE.createCompany();
+ companyD.setName("VALUED");
+
+ resD.getContents().add(companyD);
+ resA.getContents().add(companyA);
+ resB.getContents().add(companyB);
+
+ Supplier supplier = Model1Factory.eINSTANCE.createSupplier();
+ PurchaseOrder purchaseOrder = Model1Factory.eINSTANCE.createPurchaseOrder();
+
+ supplier.getPurchaseOrders().add(purchaseOrder);
+ resD.getContents().add(supplier);
+ resA.getContents().add(purchaseOrder);
+
+ CDOXATransaction transSet = CDOUtil.createXATransaction();
+
+ transSet.add(CDOUtil.getViewSet(resourceSet));
+
+ transactionA1.commit();
+
+ resD.save(null);
+ }
+
+ {
+ ResourceSet resourceSet = new ResourceSetImpl();
+ CDOSession session = openSession();
+ CDOTransaction transaction = session.openTransaction(resourceSet);
+
+ CDOSession session2 = openSession(REPOSITORY2_NAME);
+ CDOTransaction transaction2 = session2.openTransaction(resourceSet);
+
+ CDOViewSet set = CDOUtil.getViewSet(resourceSet);
+ assertNotNull(set);
+
+ resourceSet.getPackageRegistry().put(Model1Package.eINSTANCE.getNsURI(), Model1Package.eINSTANCE);
+ resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put("file", new XMIResourceFactoryImpl());
+
+ Resource resD = resourceSet.getResource(URI.createFileURI("c:\\1.xml"), true);
+ CDOResource resA = transaction.getResource("/resA");
+ CDOResource resB = transaction2.getResource("/resB");
+ Company companyA = (Company)resA.getContents().get(0);
+ Company companyB = (Company)resB.getContents().get(0);
+ Company companyD = (Company)resD.getContents().get(0);
+
+ assertNotSame(resA.getURI(), resB.getURI());
+ assertNotSame(resA.getPath(), "/resA");
+ assertNotSame(resB.getPath(), "/resB");
+ assertNotSame(resA.cdoView(), transaction2);
+ assertNotSame(resB.cdoView(), transaction);
+
+ assertEquals("VALUEA", companyA.getName());
+ assertEquals("VALUEB", companyB.getName());
+ assertEquals("VALUED", companyD.getName());
+
+ Supplier supplierD = (Supplier)resD.getContents().get(1);
+ PurchaseOrder pO = supplierD.getPurchaseOrders().get(0);
+ assertEquals(transaction, pO.cdoView());
+ assertEquals(supplierD, pO.getSupplier());
+ }
+ }
+
+ public void testManyViewsOnOneResourceSet() throws Exception
+ {
+ createRepository(REPOSITORY2_NAME);
+ {
+ CDOSession sessionA = openSession();
+ CDOSession sessionB = openSession(REPOSITORY2_NAME);
+
+ ResourceSet resourceSet = new ResourceSetImpl();
+
+ sessionA.getPackageRegistry().putEPackage(Model1Package.eINSTANCE);
+ sessionB.getPackageRegistry().putEPackage(Model1Package.eINSTANCE);
+
+ CDOTransaction transactionA1 = sessionA.openTransaction(resourceSet);
+ CDOTransaction transactionB1 = sessionB.openTransaction(resourceSet);
+
+ CDOResource resA = transactionA1.createResource("/resA");
+ CDOResource resB = transactionB1.createResource("/resB");
+
+ Supplier supplier = Model1Factory.eINSTANCE.createSupplier();
+ PurchaseOrder purchaseOrder = Model1Factory.eINSTANCE.createPurchaseOrder();
+
+ supplier.getPurchaseOrders().add(purchaseOrder);
+ resB.getContents().add(supplier);
+ resA.getContents().add(purchaseOrder);
+
+ CDOXATransaction transSet = CDOUtil.createXATransaction();
+ transSet.add(CDOUtil.getViewSet(resourceSet));
+
+ transactionA1.commit();
+ }
+
+ {
+ ResourceSet resourceSet = new ResourceSetImpl();
+ CDOSession sessionA = openSession();
+ CDOTransaction transactionA = sessionA.openTransaction(resourceSet);
+
+ CDOSession sessionB = openSession(REPOSITORY2_NAME);
+ CDOTransaction transactionB = sessionB.openTransaction(resourceSet);
+
+ CDOResource resA = transactionA.getResource("/resA");
+ assertNotNull(resA);
+
+ CDOResource resB = transactionB.getResource("/resB");
+ assertNotNull(resB);
+
+ Supplier supplierB = (Supplier)resB.getContents().get(0);
+ PurchaseOrder pO = supplierB.getPurchaseOrders().get(0);
+
+ assertEquals(transactionA, pO.cdoView());
+
+ assertEquals(transactionB, supplierB.cdoView());
+
+ assertEquals(supplierB, pO.getSupplier());
+ assertEquals(supplierB.getPurchaseOrders().get(0), pO);
+
+ }
+ }
+
+ private EPackage createDynamicEPackage()
+ {
+ final EcoreFactory efactory = EcoreFactory.eINSTANCE;
+ final EcorePackage epackage = EcorePackage.eINSTANCE;
+
+ EClass schoolBookEClass = efactory.createEClass();
+ schoolBookEClass.setName("SchoolBook");
+
+ // create a new attribute for this EClass
+ EAttribute level = efactory.createEAttribute();
+ level.setName("level");
+ level.setEType(epackage.getEInt());
+ schoolBookEClass.getEStructuralFeatures().add(level);
+
+ // Create a new EPackage and add the new EClasses
+ EPackage schoolPackage = efactory.createEPackage();
+ schoolPackage.setName("elv");
+ schoolPackage.setNsPrefix("elv");
+ schoolPackage.setNsURI("http:///www.elver.org/School");
+ schoolPackage.getEClassifiers().add(schoolBookEClass);
+ return schoolPackage;
+
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/InitialTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/InitialTest.java
index 200f14e5fa..e80a4a60c2 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/InitialTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/InitialTest.java
@@ -21,6 +21,7 @@ import org.eclipse.emf.cdo.tests.model1.OrderAddress;
import org.eclipse.emf.cdo.tests.model1.OrderDetail;
import org.eclipse.emf.cdo.tests.model1.PurchaseOrder;
import org.eclipse.emf.cdo.tests.model1.Supplier;
+import org.eclipse.emf.cdo.util.CDOURIUtil;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.net4j.buffer.IBufferHandler;
@@ -151,7 +152,7 @@ public class InitialTest extends AbstractCDOTest
msg("Creating resource");
CDOResource resource = transaction.createResource("/test1");
assertNew(resource, transaction);
- assertEquals(URI.createURI("cdo:/test1"), resource.getURI());
+ assertEquals(URI.createURI("cdo://" + session.getRepositoryUUID() + "/test1"), resource.getURI());
ResourceSet expected = transaction.getResourceSet();
ResourceSet actual = resource.getResourceSet();
assertEquals(expected, actual);
@@ -174,11 +175,14 @@ public class InitialTest extends AbstractCDOTest
msg("Opening transaction");
CDOTransaction transaction = session.openTransaction(resourceSet);
-
+ final URI newURI = CDOURIUtil.createResourceURI(session, "test1");
msg("Verifying resource");
assertNew(resource, transaction);
- assertEquals(uri, resource.getURI());
+ assertEquals(newURI, resource.getURI());
assertEquals(transaction.getResourceSet(), resource.getResourceSet());
+
+ assertEquals(resource, resourceSet.getResource(CDOURIUtil.createResourceURI(session, "test1"), false));
+
}
public void testAttachViewWithObject() throws Exception
@@ -225,7 +229,7 @@ public class InitialTest extends AbstractCDOTest
msg("Verifying resource");
assertNew(resource, transaction);
- assertEquals(uri, resource.getURI());
+ assertEquals(CDOURIUtil.createResourceURI(session, uri.path()), resource.getURI());
assertEquals(transaction.getResourceSet(), resource.getResourceSet());
msg("Verifying contents");
@@ -447,18 +451,35 @@ public class InitialTest extends AbstractCDOTest
transaction.commit();
enableConsole();
}
+ {
+ msg("Opening transaction");
+ CDOTransaction transaction = session.openTransaction();
- msg("Opening transaction");
- CDOTransaction transaction = session.openTransaction();
+ msg("Getting resource");
+ CDOResource resource = transaction.getResource("/test1");
+ assertNotNull(resource);
+ assertEquals(URI.createURI("cdo://" + session.getRepositoryUUID() + "/test1"), resource.getURI());
+ assertEquals(transaction.getResourceSet(), resource.getResourceSet());
+ assertEquals(1, transaction.getResourceSet().getResources().size());
+ assertEquals(CDOState.PROXY, resource.cdoState());
+ assertEquals(transaction, resource.cdoView());
+ assertNull(resource.cdoRevision());
+ }
+ {
+ msg("Opening transaction");
+ CDOTransaction transaction = session.openTransaction();
- msg("Getting resource");
- CDOResource resource = transaction.getResource("/test1");
- assertNotNull(resource);
- assertEquals(URI.createURI("cdo:/test1"), resource.getURI());
- assertEquals(transaction.getResourceSet(), resource.getResourceSet());
- assertEquals(CDOState.PROXY, resource.cdoState());
- assertEquals(transaction, resource.cdoView());
- assertNull(resource.cdoRevision());
+ msg("Getting resource");
+ CDOResource resource = (CDOResource)transaction.getResourceSet().getResource(
+ CDOURIUtil.createResourceURI(transaction, "/test1"), true);
+ assertNotNull(resource);
+ assertEquals(URI.createURI("cdo://" + session.getRepositoryUUID() + "/test1"), resource.getURI());
+ assertEquals(transaction.getResourceSet(), resource.getResourceSet());
+ assertEquals(1, transaction.getResourceSet().getResources().size());
+ assertEquals(CDOState.PROXY, resource.cdoState());
+ assertEquals(transaction, resource.cdoView());
+ assertNull(resource.cdoRevision());
+ }
}
public void testGetContents() throws Exception
@@ -580,7 +601,7 @@ public class InitialTest extends AbstractCDOTest
msg("Getting resource");
CDOResource resource = transaction.getResource("/test1");
assertNotNull(resource);
- assertEquals(URI.createURI("cdo:/test1"), resource.getURI());
+ assertEquals(URI.createURI("cdo://" + session.getRepositoryUUID() + "/test1"), resource.getURI());
assertEquals(transaction.getResourceSet(), resource.getResourceSet());
assertEquals(CDOState.PROXY, resource.cdoState());
assertEquals(transaction, resource.cdoView());
@@ -774,6 +795,8 @@ public class InitialTest extends AbstractCDOTest
resource1.getContents().add(cat1);
cat1.getCategories().add(cat2);
+ assertEquals(null, cat2.cdoResource());
+ assertEquals(resource1, cat1.cdoResource());
assertEquals(null, ((InternalEObject)cat2).eDirectResource());
assertEquals(resource1, ((InternalEObject)cat1).eDirectResource());
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/InvalidationTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/InvalidationTest.java
index 8ce0145543..6b21cc5f94 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/InvalidationTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/InvalidationTest.java
@@ -22,6 +22,7 @@ import org.eclipse.emf.cdo.tests.model1.Company;
import org.eclipse.emf.cdo.tests.model1.Model1Factory;
import org.eclipse.emf.internal.cdo.CDOTransactionImpl;
+import org.eclipse.emf.internal.cdo.util.FSMUtil;
import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.event.IListener;
@@ -628,4 +629,63 @@ public class InvalidationTest extends AbstractCDOTest
assertEquals(false, timeOuterB_2.timedOut());
assertEquals(false, timeOuterC_2.timedOut());
}
+
+
+ public void testDetach() throws Exception
+ {
+ msg("Creating category1");
+ final Category categoryA = Model1Factory.eINSTANCE.createCategory();
+ categoryA.setName("category1");
+
+ msg("Opening sessionA");
+ final CDOSession sessionA = openModel1Session();
+
+ msg("Attaching transaction");
+ final CDOTransaction transaction = sessionA.openTransaction();
+
+ msg("Creating resource");
+ final CDOResource resourceA = transaction.createResource("/test1");
+
+ msg("Adding company");
+ resourceA.getContents().add(categoryA);
+
+ msg("Committing");
+ transaction.commit();
+
+ // ************************************************************* //
+
+ msg("Opening sessionB");
+ final CDOSession sessionB = openModel1Session();
+
+ msg("Attaching viewB");
+ final CDOView viewB = sessionB.openTransaction();
+
+ msg("Loading resource");
+ final CDOResource resourceB = viewB.getResource("/test1");
+ assertProxy(resourceB);
+
+ EList<EObject> contents = resourceB.getContents();
+ final Category categoryB = (Category)contents.get(0);
+
+ // ************************************************************* //
+
+ resourceA.getContents().remove(categoryA);
+ ITimeOuter timeOuter = new PollingTimeOuter(20, 100)
+ {
+ @Override
+ protected boolean successful()
+ {
+ return FSMUtil.isTransient(categoryB);
+ }
+ };
+
+ msg("Checking before commit");
+ assertEquals(true, timeOuter.timedOut());
+
+ msg("Committing");
+ transaction.commit();
+
+ msg("Checking after commit");
+ assertEquals(false, timeOuter.timedOut());
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ResourceTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ResourceTest.java
index afb36d7bbc..3ee8650932 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ResourceTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ResourceTest.java
@@ -1,6 +1,7 @@
package org.eclipse.emf.cdo.tests;
import org.eclipse.emf.cdo.CDOSession;
+import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.CDOTransaction;
import org.eclipse.emf.cdo.CDOView;
import org.eclipse.emf.cdo.eresource.CDOResource;
@@ -10,12 +11,21 @@ import org.eclipse.emf.cdo.server.IStore;
import org.eclipse.emf.cdo.tests.model1.Model1Factory;
import org.eclipse.emf.cdo.tests.model1.Product;
import org.eclipse.emf.cdo.tests.model1.VAT;
+import org.eclipse.emf.cdo.util.CDOURIUtil;
+import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import java.util.ArrayList;
import java.util.List;
+import junit.framework.Assert;
+
public class ResourceTest extends AbstractCDOTest
{
/**
@@ -54,6 +64,151 @@ public class ResourceTest extends AbstractCDOTest
session.close();
}
+ public void testCreateResource_FromResourceSet() throws Exception
+ {
+ final URI uri = URI.createURI("cdo:/test1");
+
+ msg("Creating resourceSet");
+ ResourceSet resourceSet = new ResourceSetImpl();
+
+ msg("Opening session");
+ CDOSession session = openModel1Session();
+
+ msg("Opening transaction");
+ CDOTransaction transaction = session.openTransaction(resourceSet);
+
+ msg("Creating resource");
+ CDOResource resource = (CDOResource)resourceSet.createResource(uri);
+ assertActive(resource);
+
+ msg("Verifying resource");
+ assertNew(resource, transaction);
+ assertEquals(CDOURIUtil.createResourceURI(session, "test1"), resource.getURI());
+ assertEquals(transaction.getResourceSet(), resource.getResourceSet());
+ }
+
+ public void testCreateResource_FromTransaction() throws Exception
+ {
+ msg("Opening session");
+ CDOSession session = openModel1Session();
+
+ msg("Opening transaction");
+ CDOTransaction transaction = session.openTransaction();
+
+ msg("Creating resource");
+ CDOResource resource = transaction.createResource("/test1");
+ assertActive(resource);
+ CDOResource resourceCopy = transaction.getOrCreateResource("/test1");
+ assertEquals(resource, resourceCopy);
+
+ msg("Verifying resource");
+ assertNew(resource, transaction);
+ assertEquals(CDOURIUtil.createResourceURI(session, "test1"), resource.getURI());
+ assertEquals(transaction.getResourceSet(), resource.getResourceSet());
+ }
+
+ public void testRemoveResourceWithCloseView() throws Exception
+ {
+ {
+ msg("Opening session");
+ CDOSession session = openModel1Session();
+
+ msg("Opening transaction");
+ CDOTransaction transaction = session.openTransaction();
+ ResourceSet rset = transaction.getResourceSet();
+ msg("Creating resource");
+ CDOResource resource = transaction.createResource("/test1");
+ assertActive(resource);
+ transaction.commit();
+
+ Assert.assertEquals(1, rset.getResources().size());
+ Assert.assertEquals(1, CDOUtil.getViewSet(rset).getViews().length);
+
+ transaction.close();
+
+ Assert.assertEquals(0, CDOUtil.getViewSet(rset).getViews().length);
+ Assert.assertEquals(0, rset.getResources().size());
+ session.close();
+ }
+ {
+ CDOSession session = openModel1Session();
+ msg("Opening transaction");
+ CDOTransaction transaction = session.openTransaction();
+
+ msg("Getting resource");
+ CDOResource resource = (CDOResource)transaction.getResourceSet().getResource(
+ CDOURIUtil.createResourceURI(transaction, "/test1"), true);
+ assertNotNull(resource);
+ assertEquals(transaction.getResourceSet(), resource.getResourceSet());
+ assertEquals(1, transaction.getResourceSet().getResources().size());
+ assertEquals(CDOState.PROXY, resource.cdoState());
+ assertEquals(transaction, resource.cdoView());
+ assertNull(resource.cdoRevision());
+ }
+ }
+
+ public void testAttachManyResources() throws Exception
+ {
+ CDOSession session = openModel1Session();
+ CDOTransaction transaction = session.openTransaction();
+
+ CDOResource resource1 = transaction.createResource("/my/resource1");
+ CDOResource resource2 = transaction.createResource("/my/resource2");
+ CDOResource resource3 = transaction.createResource("/my/resource3");
+
+ List<Resource> tobeRemoved = new ArrayList<Resource>();
+ tobeRemoved.add(resource1);
+ tobeRemoved.add(resource3);
+
+ assertEquals(3, transaction.getResourceSet().getResources().size());
+
+ transaction.getResourceSet().getResources().removeAll(tobeRemoved);
+
+ assertEquals(1, transaction.getResourceSet().getResources().size());
+ assertEquals(null, transaction.getResourceSet().getResource(resource1.getURI(), false));
+ assertEquals(resource2, transaction.getResourceSet().getResource(resource2.getURI(), false));
+ assertEquals(null, transaction.getResourceSet().getResource(resource3.getURI(), false));
+
+ transaction.getResourceSet().getResources().addAll(tobeRemoved);
+
+ assertEquals(3, transaction.getResourceSet().getResources().size());
+ assertEquals(resource1, transaction.getResourceSet().getResource(resource1.getURI(), false));
+ assertEquals(resource2, transaction.getResourceSet().getResource(resource2.getURI(), false));
+ assertEquals(resource3, transaction.getResourceSet().getResource(resource3.getURI(), false));
+
+ transaction.commit();
+
+ session.close();
+ }
+
+ public void testDetachManyResources() throws Exception
+ {
+ CDOSession session = openModel1Session();
+ CDOTransaction transaction = session.openTransaction();
+
+ CDOResource resource1 = transaction.createResource("/my/resource1");
+ CDOResource resource2 = transaction.createResource("/my/resource2");
+ CDOResource resource3 = transaction.createResource("/my/resource3");
+
+ List<Resource> tobeRemoved = new ArrayList<Resource>();
+ tobeRemoved.add(resource1);
+ tobeRemoved.add(resource3);
+
+ assertEquals(3, transaction.getResourceSet().getResources().size());
+
+ transaction.getResourceSet().getResources().removeAll(tobeRemoved);
+
+ assertEquals(1, transaction.getResourceSet().getResources().size());
+ assertEquals(null, transaction.getResourceSet().getResource(resource1.getURI(), false));
+ assertEquals(resource2, transaction.getResourceSet().getResource(resource2.getURI(), false));
+ assertEquals(null, transaction.getResourceSet().getResource(resource3.getURI(), false));
+
+ transaction.commit();
+ session.close();
+ }
+
+
+
/**
* http://bugs.eclipse.org/208689
*/
@@ -198,4 +353,5 @@ public class ResourceTest extends AbstractCDOTest
assertEquals(expected, resources.size());
}
+
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/RevisionHolderTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/RevisionHolderTest.java
index a328b00ea6..f37e6d0a7b 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/RevisionHolderTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/RevisionHolderTest.java
@@ -295,7 +295,7 @@ public class RevisionHolderTest extends AbstractOMTest
throw new UnsupportedOperationException();
}
- public CDOID getContainerID()
+ public Object getContainerID()
{
throw new UnsupportedOperationException();
}
@@ -370,7 +370,7 @@ public class RevisionHolderTest extends AbstractOMTest
throw new UnsupportedOperationException();
}
- public void setContainerID(CDOID containerID)
+ public void setContainerID(Object containerID)
{
throw new UnsupportedOperationException();
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StateMachineTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StateMachineTest.java
index 884f70d62a..ff65ede716 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StateMachineTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StateMachineTest.java
@@ -46,7 +46,7 @@ public class StateMachineTest extends AbstractCDOTest
CDOTransaction transaction = session.openTransaction();
CDOResource resource = transaction.createResource("/test1");
assertNew(resource, transaction);
- assertEquals(URI.createURI("cdo:/test1"), resource.getURI());
+ assertEquals(URI.createURI("cdo://" + session.getRepositoryUUID() + "/test1"), resource.getURI());
assertEquals(transaction.getResourceSet(), resource.getResourceSet());
// Attach single object
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ViewTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ViewTest.java
index 5fef75fbee..bd3c90d40f 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ViewTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ViewTest.java
@@ -103,10 +103,7 @@ public class ViewTest extends AbstractCDOTest
CDORevisionData revision = resource.cdoRevision().getData();
CDOResourcePackage resourcePackage = session.getPackageManager().getCDOResourcePackage();
CDOContentsFeature contentsFeature = resourcePackage.getCDOResourceClass().getCDOContentsFeature();
- assertEquals(false, revision.get(contentsFeature, 0) instanceof CDOReferenceProxy);
- assertEquals(false, revision.get(contentsFeature, 1) instanceof CDOReferenceProxy);
- assertEquals(false, revision.get(contentsFeature, 2) instanceof CDOReferenceProxy);
- assertEquals(false, revision.get(contentsFeature, 99) instanceof CDOReferenceProxy);
+ assertEquals(true, revision.get(contentsFeature, 99) instanceof CDOReferenceProxy);
assertEquals(false, revision.get(contentsFeature, 100) instanceof CDOReferenceProxy);
session.close();
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/XATransactionTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/XATransactionTest.java
new file mode 100644
index 0000000000..5c19da3a7f
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/XATransactionTest.java
@@ -0,0 +1,222 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo.tests;
+
+import org.eclipse.emf.cdo.CDOSavepoint;
+import org.eclipse.emf.cdo.CDOSession;
+import org.eclipse.emf.cdo.CDOTransaction;
+import org.eclipse.emf.cdo.CDOXATransaction;
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.tests.model1.Model1Factory;
+import org.eclipse.emf.cdo.tests.model1.Model1Package;
+import org.eclipse.emf.cdo.tests.model1.PurchaseOrder;
+import org.eclipse.emf.cdo.tests.model1.Supplier;
+import org.eclipse.emf.cdo.tests.model4.GenRefSingleNonContained;
+import org.eclipse.emf.cdo.tests.model4.model4Factory;
+import org.eclipse.emf.cdo.tests.model4.model4Package;
+import org.eclipse.emf.cdo.util.CDOUtil;
+
+import org.eclipse.emf.internal.cdo.CDOTransactionImpl;
+
+import org.eclipse.net4j.util.transaction.TransactionException;
+
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+
+import java.util.Date;
+
+/**
+ * @author Simon McDuff
+ */
+public class XATransactionTest extends AbstractCDOTest
+{
+ final static public String REPOSITORY2_NAME = "repo2";
+
+ public void testRollback() throws Exception
+ {
+ createRepository(REPOSITORY2_NAME);
+
+ CDOSession sessionA = openSession();
+ CDOSession sessionB = openSession(REPOSITORY2_NAME);
+
+ ResourceSet resourceSet = new ResourceSetImpl();
+ CDOXATransaction xaTransaction = CDOUtil.createXATransaction();
+
+ CDOUtil.prepareResourceSet(resourceSet);
+ xaTransaction.add(CDOUtil.getViewSet(resourceSet));
+
+ sessionA.getPackageRegistry().putEPackage(Model1Package.eINSTANCE);
+ sessionB.getPackageRegistry().putEPackage(Model1Package.eINSTANCE);
+
+ CDOTransaction transactionA1 = sessionA.openTransaction(resourceSet);
+ CDOTransaction transactionB1 = sessionB.openTransaction(resourceSet);
+
+ CDOResource resA = transactionA1.createResource("/resA");
+ CDOResource resB = transactionB1.createResource("/resB");
+
+ Supplier supplier = Model1Factory.eINSTANCE.createSupplier();
+ PurchaseOrder purchaseOrder = Model1Factory.eINSTANCE.createPurchaseOrder();
+
+ supplier.getPurchaseOrders().add(purchaseOrder);
+ resB.getContents().add(supplier);
+ resA.getContents().add(purchaseOrder);
+
+ assertNew(resA, transactionA1);
+ assertNew(resB, transactionB1);
+
+ xaTransaction.rollback();
+
+ assertTransient(resA);
+ assertTransient(resB);
+
+ xaTransaction.commit();
+ }
+
+ public void testRollback_AfterSetpoint() throws Exception
+ {
+ createRepository(REPOSITORY2_NAME);
+
+ CDOSession sessionA = openSession();
+ CDOSession sessionB = openSession(REPOSITORY2_NAME);
+
+ ResourceSet resourceSet = new ResourceSetImpl();
+ CDOXATransaction xaTransaction = CDOUtil.createXATransaction();
+
+ CDOUtil.prepareResourceSet(resourceSet);
+ xaTransaction.add(CDOUtil.getViewSet(resourceSet));
+
+ sessionA.getPackageRegistry().putEPackage(Model1Package.eINSTANCE);
+ sessionB.getPackageRegistry().putEPackage(Model1Package.eINSTANCE);
+
+ CDOTransaction transactionA1 = sessionA.openTransaction(resourceSet);
+ CDOTransaction transactionB1 = sessionB.openTransaction(resourceSet);
+
+ CDOResource resA = transactionA1.createResource("/resA");
+ CDOResource resB = transactionB1.createResource("/resB");
+
+ Supplier supplier = Model1Factory.eINSTANCE.createSupplier();
+ PurchaseOrder purchaseOrder = Model1Factory.eINSTANCE.createPurchaseOrder();
+
+ supplier.getPurchaseOrders().add(purchaseOrder);
+ resB.getContents().add(supplier);
+ resA.getContents().add(purchaseOrder);
+
+ assertNew(resA, transactionA1);
+ assertNew(resB, transactionB1);
+
+ CDOSavepoint savepoint1 = xaTransaction.setSavepoint();
+
+ purchaseOrder.setDate(new Date());
+ supplier.setCity("OTTAWA");
+
+ CDOSavepoint savepoint2 = xaTransaction.setSavepoint();
+
+ savepoint1.rollback();
+
+ assertNew(resA, transactionA1);
+ assertNew(resB, transactionB1);
+
+ assertEquals(null, supplier.getCity());
+ assertEquals(null, purchaseOrder.getDate());
+ assertEquals(supplier, purchaseOrder.getSupplier());
+
+ try
+ {
+ savepoint2.rollback();
+ fail("Should have an exception");
+ }
+ catch (Exception ex)
+ {
+
+ }
+
+ xaTransaction.commit();
+
+ }
+
+ public void testCommitFromTransactionDisabled() throws Exception
+ {
+ createRepository(REPOSITORY2_NAME);
+ {
+ CDOSession sessionA = openSession();
+ CDOSession sessionB = openSession(REPOSITORY2_NAME);
+ ResourceSet resourceSet = new ResourceSetImpl();
+ sessionA.getPackageRegistry().putEPackage(model4Package.eINSTANCE);
+ sessionB.getPackageRegistry().putEPackage(model4Package.eINSTANCE);
+ CDOTransactionImpl transactionA1 = (CDOTransactionImpl)sessionA.openTransaction(resourceSet);
+ CDOTransactionImpl transactionB1 = (CDOTransactionImpl)sessionB.openTransaction(resourceSet);
+
+ CDOResource resA = transactionA1.createResource("/resA");
+ CDOResource resB = transactionB1.createResource("/resB");
+
+ transactionA1.setTransactionStrategy(null);
+ GenRefSingleNonContained objectFromResA = model4Factory.eINSTANCE.createGenRefSingleNonContained();
+ GenRefSingleNonContained objectFromResB = model4Factory.eINSTANCE.createGenRefSingleNonContained();
+
+ objectFromResA.setElement(objectFromResB);
+ resA.getContents().add(objectFromResA);
+ resB.getContents().add(objectFromResB);
+
+ CDOXATransaction transSet = CDOUtil.createXATransaction();
+
+ transSet.setAllowRequestFromTransactionEnabled(false);
+
+ transSet.add(CDOUtil.getViewSet(resourceSet));
+
+ try
+ {
+ transactionA1.commit();
+ fail("We should have an exception");
+ }
+ catch (TransactionException exp)
+ {
+
+ }
+ transSet.commit();
+ }
+ }
+
+ public void testNotUsingXATransaction_Exception() throws Exception
+ {
+ createRepository(REPOSITORY2_NAME);
+ {
+ CDOSession sessionA = openSession();
+ CDOSession sessionB = openSession(REPOSITORY2_NAME);
+ ResourceSet resourceSet = new ResourceSetImpl();
+ sessionA.getPackageRegistry().putEPackage(model4Package.eINSTANCE);
+ sessionB.getPackageRegistry().putEPackage(model4Package.eINSTANCE);
+ CDOTransactionImpl transactionA1 = (CDOTransactionImpl)sessionA.openTransaction(resourceSet);
+ CDOTransactionImpl transactionB1 = (CDOTransactionImpl)sessionB.openTransaction(resourceSet);
+
+ CDOResource resA = transactionA1.createResource("/resA");
+ CDOResource resB = transactionB1.createResource("/resB");
+ GenRefSingleNonContained objectFromResA = model4Factory.eINSTANCE.createGenRefSingleNonContained();
+ GenRefSingleNonContained objectFromResB = model4Factory.eINSTANCE.createGenRefSingleNonContained();
+
+ objectFromResA.setElement(objectFromResB);
+ resA.getContents().add(objectFromResA);
+ resB.getContents().add(objectFromResB);
+
+ try
+ {
+ transactionA1.commit();
+ fail("We should have an exception");
+ }
+ catch (TransactionException exp)
+ {
+ }
+ CDOXATransaction transSet = CDOUtil.createXATransaction();
+ transSet.add(CDOUtil.getViewSet(resourceSet));
+
+ transactionA1.commit();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_246622_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_246622_Test.java
new file mode 100644
index 0000000000..91d0b00b5d
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_246622_Test.java
@@ -0,0 +1,135 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo.tests.bugzilla;
+
+import org.eclipse.emf.cdo.CDOSession;
+import org.eclipse.emf.cdo.CDOTransaction;
+import org.eclipse.emf.cdo.common.model.CDOFeature;
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.tests.AbstractCDOTest;
+import org.eclipse.emf.cdo.tests.model1.Model1Factory;
+import org.eclipse.emf.cdo.tests.model1.Model1Package;
+import org.eclipse.emf.cdo.tests.model1.Order;
+import org.eclipse.emf.cdo.tests.model1.OrderDetail;
+import org.eclipse.emf.cdo.tests.model1.PurchaseOrder;
+import org.eclipse.emf.cdo.tests.model1.Supplier;
+
+/**
+ * 246622: CDOStore.set doesn't affect variable correctly - Could cause memory retention
+ * <p>
+ * See https://bugs.eclipse.org/243310
+ *
+ * @author Simon McDuff
+ */
+public class Bugzilla_246622_Test extends AbstractCDOTest
+{
+ public void testContainerAndMany() throws Exception
+ {
+ CDOSession session = openModel1Session();
+
+ CDOTransaction transaction1 = session.openTransaction();
+ CDOResource res = transaction1.createResource("/test1");
+ Order order = Model1Factory.eINSTANCE.createOrder();
+ OrderDetail orderDetail = Model1Factory.eINSTANCE.createOrderDetail();
+
+ res.getContents().add(order);
+ order.getOrderDetails().add(orderDetail);
+ CDOFeature order_OrderDetailFeature = session.getPackageManager().convert(Model1Package.eINSTANCE.getOrder_OrderDetails());
+ assertEquals(orderDetail, order.cdoRevision().getData().get(order_OrderDetailFeature, 0));
+
+ assertEquals(order, orderDetail.cdoRevision().getData().getContainerID());
+
+ Order order2 = Model1Factory.eINSTANCE.createOrder();
+ OrderDetail orderDetail2 = Model1Factory.eINSTANCE.createOrderDetail();
+
+ order2.getOrderDetails().add(orderDetail2);
+ res.getContents().add(order2);
+
+ assertEquals(orderDetail2, order2.cdoRevision().getData().get(order_OrderDetailFeature, 0));
+ assertEquals(order2, orderDetail2.cdoRevision().getData().getContainerID());
+
+ msg("Committing");
+ transaction1.commit();
+
+ assertEquals(orderDetail.cdoID(), order.cdoRevision().getData().get(order_OrderDetailFeature, 0));
+ assertEquals(orderDetail2.cdoID(), order2.cdoRevision().getData().get(order_OrderDetailFeature, 0));
+
+ assertEquals(order.cdoID(), orderDetail.cdoRevision().getData().getContainerID());
+ assertEquals(order2.cdoID(), orderDetail2.cdoRevision().getData().getContainerID());
+
+ Order order3 = Model1Factory.eINSTANCE.createOrder();
+
+ res.getContents().add(order3);
+ order3.getOrderDetails().add(orderDetail2);
+
+ assertEquals(orderDetail2.cdoID(), order3.cdoRevision().getData().get(order_OrderDetailFeature, 0));
+ assertEquals(order3, orderDetail2.cdoRevision().getData().getContainerID());
+
+ msg("Committing");
+ transaction1.commit();
+ }
+ public void testSet() throws Exception
+ {
+ CDOSession session = openModel1Session();
+
+ CDOTransaction transaction1 = session.openTransaction();
+ CDOResource res = transaction1.createResource("/test1");
+
+
+ msg("Test set with link before");
+ PurchaseOrder purchaseOrder = Model1Factory.eINSTANCE.createPurchaseOrder();
+ Supplier supplier = Model1Factory.eINSTANCE.createSupplier();
+
+ purchaseOrder.setSupplier(supplier);
+
+ res.getContents().add(purchaseOrder);
+ res.getContents().add(supplier);
+
+ CDOFeature supplier_PurchaseOrder = session.getPackageManager().convert(Model1Package.eINSTANCE.getSupplier_PurchaseOrders());
+ CDOFeature purchaseOrder_Supplier = session.getPackageManager().convert(Model1Package.eINSTANCE.getPurchaseOrder_Supplier());
+
+
+ assertEquals(supplier, purchaseOrder.cdoRevision().getData().get(purchaseOrder_Supplier, 0));
+ assertEquals(purchaseOrder, supplier.cdoRevision().getData().get(supplier_PurchaseOrder, 0));
+
+ msg("Test set with link after");
+ PurchaseOrder purchaseOrder2 = Model1Factory.eINSTANCE.createPurchaseOrder();
+ Supplier supplier2 = Model1Factory.eINSTANCE.createSupplier();
+
+ res.getContents().add(purchaseOrder2);
+ res.getContents().add(supplier2);
+ purchaseOrder2.setSupplier(supplier2);
+
+ assertEquals(supplier2, purchaseOrder2.cdoRevision().getData().get(purchaseOrder_Supplier, 0));
+ assertEquals(purchaseOrder2, supplier2.cdoRevision().getData().get(supplier_PurchaseOrder, 0));
+
+ msg("Committing");
+ transaction1.commit();
+
+
+ assertEquals(supplier2.cdoID(), purchaseOrder2.cdoRevision().getData().get(purchaseOrder_Supplier, 0));
+ assertEquals(purchaseOrder2.cdoID(), supplier2.cdoRevision().getData().get(supplier_PurchaseOrder, 0));
+
+ assertEquals(supplier.cdoID(), purchaseOrder.cdoRevision().getData().get(purchaseOrder_Supplier, 0));
+ assertEquals(purchaseOrder.cdoID(), supplier.cdoRevision().getData().get(supplier_PurchaseOrder, 0));
+
+ msg("Test set with persisted CDOID");
+ PurchaseOrder purchaseOrder3 = Model1Factory.eINSTANCE.createPurchaseOrder();
+ purchaseOrder3.setSupplier(supplier2);
+ res.getContents().add(purchaseOrder3);
+
+ assertEquals(supplier2.cdoID(), purchaseOrder3.cdoRevision().getData().get(purchaseOrder_Supplier, 0));
+ assertEquals(purchaseOrder3, supplier2.cdoRevision().getData().get(supplier_PurchaseOrder, 1));
+
+ msg("Committing");
+ transaction1.commit();
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/logic/TestLogic.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/logic/TestLogic.java
index 6ff3df60ca..3f4be3aa8f 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/logic/TestLogic.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/store/logic/TestLogic.java
@@ -10,6 +10,7 @@
**************************************************************************/
package org.eclipse.emf.cdo.tests.store.logic;
+import org.eclipse.emf.cdo.common.CDOProtocolView;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDMetaRange;
import org.eclipse.emf.cdo.common.id.CDOIDTemp;
@@ -26,7 +27,8 @@ import org.eclipse.emf.cdo.internal.common.revision.CDORevisionImpl;
import org.eclipse.emf.cdo.internal.server.Repository;
import org.eclipse.emf.cdo.internal.server.Session;
import org.eclipse.emf.cdo.internal.server.Transaction;
-import org.eclipse.emf.cdo.internal.server.Transaction.TransactionPackageManager;
+import org.eclipse.emf.cdo.internal.server.Transaction.InternalCommitContext;
+import org.eclipse.emf.cdo.internal.server.TransactionCommitContextImpl.TransactionPackageManager;
import org.eclipse.emf.cdo.internal.server.protocol.CDOServerProtocol;
import org.eclipse.emf.cdo.server.IStore;
import org.eclipse.emf.cdo.server.IRepository.Props;
@@ -181,20 +183,22 @@ public abstract class TestLogic extends AbstractOMTest
{
private int viewID;
- private long timeStamp;
-
private CDOServerProtocol protocol;
private Session session;
private Transaction transaction;
+ private InternalCommitContext transactionCommitContext;
+
private List<CDOPackage> newPackages = new ArrayList<CDOPackage>();
private List<CDORevision> newObjects = new ArrayList<CDORevision>();
private List<CDORevisionDelta> dirtyObjectDeltas = new ArrayList<CDORevisionDelta>();
+ private List<CDOID> detachedObjects = new ArrayList<CDOID>();
+
public CommitTemplate()
{
this(1, 12345);
@@ -203,12 +207,12 @@ public abstract class TestLogic extends AbstractOMTest
public CommitTemplate(int viewID, long timeStamp)
{
this.viewID = viewID;
- this.timeStamp = timeStamp;
protocol = createProtocol();
session = repository.getSessionManager().openSession(protocol, true);
protocol.setInfraStructure(session);
transaction = createTransaction(session);
- transaction.preCommit();
+ transactionCommitContext = transaction.createCommitContext(timeStamp);
+ transactionCommitContext.preCommit();
}
public Session getSession()
@@ -218,8 +222,13 @@ public abstract class TestLogic extends AbstractOMTest
public Transaction run() throws Exception
{
- transaction.commit(getNewPackages(), getNewObjects(), getDirtyObjectDeltas());
- transaction.postCommit(true);
+ transactionCommitContext.setNewPackages(getNewPackages());
+ transactionCommitContext.setNewObjects(getNewObjects());
+ transactionCommitContext.setDirtyObjectDeltas(getDirtyObjectDeltas());
+ transactionCommitContext.setDetachedObjects(getDetachedObjects());
+ transactionCommitContext.write();
+ transactionCommitContext.commit();
+ transactionCommitContext.postCommit(true);
return transaction;
}
@@ -247,7 +256,7 @@ public abstract class TestLogic extends AbstractOMTest
idRange = CDOSessionImpl.registerEPackage(ePackage, 1, null, null);
}
- TransactionPackageManager packageManager = transaction.getPackageManager();
+ TransactionPackageManager packageManager = transactionCommitContext.getPackageManager();
CDOPackage newPackage = CDOModelUtil.createPackage(packageManager, uri, name, ecore, dynamic, idRange, parentURI);
ModelUtil.initializeCDOPackage(ePackage, newPackage);
packageManager.addPackage(newPackage);
@@ -264,8 +273,10 @@ public abstract class TestLogic extends AbstractOMTest
public Revision addNewObject(int id, EClass eClass)
{
+
String uri = eClass.getEPackage().getNsURI();
- CDOPackage cdoPackage = transaction.getPackageManager().lookupPackage(uri);
+
+ CDOPackage cdoPackage = transactionCommitContext.getPackageManager().lookupPackage(uri);
CDOClass cdoClass = cdoPackage.lookupClass(eClass.getClassifierID());
return addRevision(id, cdoClass);
}
@@ -290,7 +301,7 @@ public abstract class TestLogic extends AbstractOMTest
protected Transaction createTransaction(Session session)
{
- return session.openTransaction(viewID, timeStamp);
+ return (Transaction)session.openView(viewID, CDOProtocolView.Type.TRANSACTION);
}
private CDOPackage[] getNewPackages()
@@ -307,6 +318,11 @@ public abstract class TestLogic extends AbstractOMTest
{
return dirtyObjectDeltas.toArray(new CDORevisionDelta[dirtyObjectDeltas.size()]);
}
+
+ private CDOID[] getDetachedObjects()
+ {
+ return detachedObjects.toArray(new CDOID[detachedObjects.size()]);
+ }
}
/**
diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java
index 9857563d2e..920c02dcea 100644
--- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java
+++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/editor/CDOEditor.java
@@ -22,7 +22,7 @@ import org.eclipse.emf.cdo.internal.ui.dialogs.BulkAddDialog;
import org.eclipse.emf.cdo.internal.ui.dialogs.RollbackTransactionDialog;
import org.eclipse.emf.cdo.ui.CDOEventHandler;
import org.eclipse.emf.cdo.ui.CDOLabelProvider;
-import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.cdo.util.CDOURIUtil;
import org.eclipse.emf.internal.cdo.CDOLegacyImpl;
import org.eclipse.emf.internal.cdo.CDOStateMachine;
@@ -1036,7 +1036,7 @@ public class CDOEditor extends MultiPageEditorPart implements IEditingDomainProv
}
else
{
- URI resourceURI = CDOUtil.createResourceURI(resourcePath);
+ URI resourceURI = CDOURIUtil.createResourceURI(view, resourcePath);
viewerInput = resourceSet.getResource(resourceURI, true);
}
diff --git a/plugins/org.eclipse.emf.cdo/.settings/.api_filters b/plugins/org.eclipse.emf.cdo/.settings/.api_filters
index e13268d3ac..5948fb01d3 100644
--- a/plugins/org.eclipse.emf.cdo/.settings/.api_filters
+++ b/plugins/org.eclipse.emf.cdo/.settings/.api_filters
@@ -14,6 +14,11 @@
</filter>
</resource>
<resource path="src/org/eclipse/emf/internal/cdo/CDOViewImpl.java" type="org.eclipse.emf.internal.cdo.CDOViewImpl">
+ <filter id="1143996420">
+ <message_arguments>
+ <message_argument value="org.eclipse.emf.internal.cdo.CDOViewImpl"/>
+ </message_arguments>
+ </filter>
<filter id="574619656">
<message_arguments>
<message_argument value="CDOIDProvider"/>
@@ -42,12 +47,40 @@
</message_arguments>
</filter>
</resource>
+ <resource path="src/org/eclipse/emf/internal/cdo/CDOXATransactionCommitContext.java" type="org.eclipse.emf.internal.cdo.CDOXATransactionCommitContext">
+ <filter id="643846161">
+ <message_arguments>
+ <message_argument value="CommitTransactionResult"/>
+ <message_argument value="CDOXATransactionCommitContext"/>
+ <message_argument value="setResult(CommitTransactionResult)"/>
+ </message_arguments>
+ </filter>
+ <filter id="643846161">
+ <message_arguments>
+ <message_argument value="CommitTransactionResult"/>
+ <message_argument value="CDOXATransactionCommitContext"/>
+ <message_argument value="postCommit(CommitTransactionResult)"/>
+ </message_arguments>
+ </filter>
+ <filter id="643842064">
+ <message_arguments>
+ <message_argument value="CommitTransactionResult"/>
+ <message_argument value="CDOXATransactionCommitContext"/>
+ <message_argument value="getResult()"/>
+ </message_arguments>
+ </filter>
+ </resource>
<resource path="src/org/eclipse/emf/cdo/eresource/impl/CDOResourceFactoryImpl.java" type="org.eclipse.emf.cdo.eresource.impl.CDOResourceFactoryImpl">
<filter id="1143996420">
<message_arguments>
<message_argument value="CDOResourceFactoryImpl(CDOViewSet)"/>
</message_arguments>
</filter>
+ <filter id="1143996420">
+ <message_arguments>
+ <message_argument value="org.eclipse.emf.cdo.eresource.impl.CDOResourceFactoryImpl"/>
+ </message_arguments>
+ </filter>
</resource>
<resource path="src/org/eclipse/emf/internal/cdo/CDONotificationBuilder.java" type="org.eclipse.emf.internal.cdo.CDONotificationBuilder">
<filter id="574619656">
@@ -81,6 +114,15 @@
</message_arguments>
</filter>
</resource>
+ <resource path="src/org/eclipse/emf/internal/cdo/CDOCommitContext.java" type="org.eclipse.emf.internal.cdo.CDOCommitContext">
+ <filter id="643846161">
+ <message_arguments>
+ <message_argument value="CommitTransactionResult"/>
+ <message_argument value="CDOCommitContext"/>
+ <message_argument value="postCommit(CommitTransactionResult)"/>
+ </message_arguments>
+ </filter>
+ </resource>
<resource path="src/org/eclipse/emf/internal/cdo/CDOStateMachine.java" type="org.eclipse.emf.internal.cdo.CDOStateMachine">
<filter id="643846161">
<message_arguments>
@@ -98,6 +140,22 @@
</message_arguments>
</filter>
</resource>
+ <resource path="src/org/eclipse/emf/internal/cdo/CDOXATransactionImpl.java" type="org.eclipse.emf.internal.cdo.CDOXATransactionImpl$CDOXAState">
+ <filter id="643846161">
+ <message_arguments>
+ <message_argument value="CommitTransactionResult"/>
+ <message_argument value="CDOXAState"/>
+ <message_argument value="check_result(CommitTransactionResult)"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/emf/internal/cdo/CDOAuditImpl.java" type="org.eclipse.emf.internal.cdo.CDOAuditImpl">
+ <filter id="1143996420">
+ <message_arguments>
+ <message_argument value="org.eclipse.emf.internal.cdo.CDOAuditImpl"/>
+ </message_arguments>
+ </filter>
+ </resource>
<resource path="src/org/eclipse/emf/cdo/CDORevisionManager.java" type="org.eclipse.emf.cdo.CDORevisionManager">
<filter id="574619656">
<message_arguments>
@@ -112,5 +170,10 @@
<message_argument value="prepareResourceSet(ResourceSet)"/>
</message_arguments>
</filter>
+ <filter id="1143996420">
+ <message_arguments>
+ <message_argument value="org.eclipse.emf.cdo.util.CDOUtil"/>
+ </message_arguments>
+ </filter>
</resource>
</component>
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOSavepoint.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOSavepoint.java
index 832fc8f559..db8d8b6af8 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOSavepoint.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOSavepoint.java
@@ -8,11 +8,12 @@
* Contributors:
* Simon McDuff - initial API and implementation
* Eike Stepper - maintenance
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo;
/**
- * Creates a save point in a {@link CDOTransaction} that can be used to roll back a part of the transaction.
+ * Creates a save point in a {@link CDOUserTransaction} that can be used to roll back a part of the transaction.
* <p>
* <b>Note:</b> Save points do not flush to disk. Everything is done in memory on the client side.
*
@@ -21,7 +22,7 @@ package org.eclipse.emf.cdo;
*/
public interface CDOSavepoint
{
- public CDOTransaction getTransaction();
+ public CDOUserTransaction getUserTransaction();
public CDOSavepoint getNextSavepoint();
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransaction.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransaction.java
index f3cabba759..768a13e4d1 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransaction.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransaction.java
@@ -9,29 +9,27 @@
* Eike Stepper - initial API and implementation
* Simon McDuff - http://bugs.eclipse.org/201266
* Simon McDuff - http://bugs.eclipse.org/215688
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.model.CDOClass;
-import org.eclipse.emf.cdo.common.model.CDOPackage;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.eresource.CDOResource;
-import org.eclipse.net4j.util.transaction.TransactionException;
-
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.resource.ResourceSet;
-import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* @author Eike Stepper
* @noimplement This interface is not intended to be implemented by clients.
*/
-public interface CDOTransaction extends CDOView
+public interface CDOTransaction extends CDOView, CDOUserTransaction
{
public static final long DEFAULT_COMMIT_TIMEOUT = 100000L;
@@ -50,48 +48,12 @@ public interface CDOTransaction extends CDOView
public CDOObject newInstance(CDOClass cdoClass);
- public void commit() throws TransactionException;
-
- public void rollback(boolean remote);
-
- /**
- * @since 2.0
- */
- public void rollback();
-
- /**
- * @since 2.0
- */
- public void rollback(CDOSavepoint savepoint, boolean remote);
-
- /**
- * @since 2.0
- */
- public void rollback(CDOSavepoint savepoint);
-
- /**
- * Creates a save point in the {@link CDOTransaction} that can be used to roll back a part of the transaction
- * <p>
- * Save points do not involve the server side, everything is done on the client side.
- * <p>
- *
- * @since 2.0
- */
- public CDOSavepoint setSavepoint();
-
- /**
- * @since 2.0
- */
- public CDOSavepoint getLastSavepoint();
-
public void addHandler(CDOTransactionHandler handler);
public void removeHandler(CDOTransactionHandler handler);
public CDOTransactionHandler[] getHandlers();
- public List<CDOPackage> getNewPackages();
-
public Map<CDOID, CDOResource> getNewResources();
public Map<CDOID, CDOObject> getNewObjects();
@@ -99,4 +61,10 @@ public interface CDOTransaction extends CDOView
public Map<CDOID, CDOObject> getDirtyObjects();
public Map<CDOID, CDORevisionDelta> getRevisionDeltas();
+
+ /**
+ * @since 2.0
+ */
+ public Set<CDOID> getDetachedObjects();
+
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransactionHandler.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransactionHandler.java
index 90ce8f8aa1..550756ec60 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransactionHandler.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransactionHandler.java
@@ -29,7 +29,7 @@ public interface CDOTransactionHandler
* Called by a <code>CDOTransaction</code> <b>before</b> an object is modified. The implementor of this method is
* allowed to throw an unchecked exception that will propagate up to the operation that is about to modify the object.
* <p>
- * Note: This method will be called at most once per object until the associated transaction is committed.
+ * <b>Note:</b> This method will be called at most once per object until the associated transaction is committed.
*/
public void modifyingObject(CDOTransaction transaction, CDOObject object, CDOFeatureDelta featureDelta);
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOUserTransaction.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOUserTransaction.java
new file mode 100644
index 0000000000..50732d43c4
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOUserTransaction.java
@@ -0,0 +1,42 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo;
+
+import org.eclipse.net4j.util.transaction.TransactionException;
+
+/**
+ * Only deal with transaction process.
+ *
+ * @author Simon McDuff
+ * @since 2.0
+ */
+public interface CDOUserTransaction
+{
+ public void commit() throws TransactionException;
+
+ public void rollback(boolean remote);
+
+ public void rollback();
+
+ public void rollback(CDOSavepoint savepoint, boolean remote);
+
+ public void rollback(CDOSavepoint savepoint);
+
+ /**
+ * Creates a save point in the {@link CDOTransaction} that can be used to roll back a part of the transaction
+ * <p>
+ * Save points do not involve the server side, everything is done on the client side.
+ * <p>
+ */
+ public CDOSavepoint setSavepoint();
+
+ public CDOSavepoint getLastSavepoint();
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOView.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOView.java
index e663788e2e..1431bdf2f9 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOView.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOView.java
@@ -10,6 +10,7 @@
* Simon McDuff - http://bugs.eclipse.org/201266
* Simon McDuff - http://bugs.eclipse.org/201997
* Simon McDuff - http://bugs.eclipse.org/233490
+ * Simon McDuff - http://bugs.eclipse.org/213402
* Victor Roldan Betancort - http://bugs.eclipse.org/208689
**************************************************************************/
package org.eclipse.emf.cdo;
@@ -40,6 +41,11 @@ public interface CDOView extends CDOProtocolView, INotifier
public CDOSession getSession();
+ /**
+ * @since 2.0
+ */
+ public CDOViewSet getViewSet();
+
public ResourceSet getResourceSet();
public boolean isDirty();
@@ -113,6 +119,12 @@ public interface CDOView extends CDOProtocolView, INotifier
/**
* @see ResourceSet#getResource(URI, boolean)
+ * @since 2.0
+ */
+ public CDOResource getResource(String path, boolean loadInDemand);
+
+ /**
+ * @see ResourceSet#getResource(URI, boolean)
*/
public CDOResource getResource(String path);
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOViewSet.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOViewSet.java
new file mode 100644
index 0000000000..60403fcd98
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOViewSet.java
@@ -0,0 +1,37 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo;
+
+import org.eclipse.emf.cdo.eresource.CDOResourceFactory;
+
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+
+/**
+ * A {@link ResourceSet} adapter to associate a set of {@link CDOView} instances.
+ * <p>
+ * <b>Note:</b> A view set must have exactly one resource set associated. A resource set can have only one view set
+ * associated.
+ *
+ * @author Simon McDuff
+ * @since 2.0
+ */
+public interface CDOViewSet extends Notifier
+{
+ public CDOView[] getViews();
+
+ public CDOResourceFactory getResourceFactory();
+
+ public EPackage.Registry getPackageRegistry();
+
+ public ResourceSet getResourceSet();
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOXATransaction.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOXATransaction.java
new file mode 100644
index 0000000000..4272cea08c
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOXATransaction.java
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo;
+
+/**
+ * @author Simon McDuff
+ * @since 2.0
+ */
+public interface CDOXATransaction extends CDOUserTransaction
+{
+ public void add(CDOViewSet viewSet);
+
+ public void remove(CDOViewSet viewSet);
+
+ /**
+ * see {@link CDOXATransaction#isAllowRequestFromTransactionEnabled()}
+ */
+
+ public void setAllowRequestFromTransactionEnabled(boolean allRequest);
+
+ /**
+ * Allow request that come from contains {@link CDOTransaction}. Default value is true.
+ * <p>
+ * If the value is true, cdoTransaction.commit() will call xaTransaction.commit and all {@link CDOXATransaction} part
+ * of XATransaction will be committed.
+ * <p>
+ * If the value is false, the user will receive an exception by calling cdoTransaction.commit(). The user can only
+ * commit from {@link CDOXATransaction}.
+ */
+ public boolean isAllowRequestFromTransactionEnabled();
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/CDOResourceFactory.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/CDOResourceFactory.java
index ced0fe2a99..803283dffe 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/CDOResourceFactory.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/CDOResourceFactory.java
@@ -7,11 +7,10 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.eresource;
-import org.eclipse.emf.cdo.eresource.impl.CDOResourceFactoryImpl;
-
import org.eclipse.emf.ecore.resource.Resource;
/**
@@ -19,5 +18,4 @@ import org.eclipse.emf.ecore.resource.Resource;
*/
public interface CDOResourceFactory extends Resource.Factory
{
- public static final CDOResourceFactory INSTANCE = CDOResourceFactoryImpl.INSTANCE;
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceFactoryImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceFactoryImpl.java
index 0624aa6dbb..0ada6f9e7d 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceFactoryImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceFactoryImpl.java
@@ -7,11 +7,18 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Simon McDuff - http://bugs.eclipse.org/213402
+ * Simon McDuff - http://bugs.eclipse.org/246705
**************************************************************************/
package org.eclipse.emf.cdo.eresource.impl;
+import org.eclipse.emf.cdo.CDOViewSet;
import org.eclipse.emf.cdo.eresource.CDOResourceFactory;
import org.eclipse.emf.cdo.eresource.EresourceFactory;
+import org.eclipse.emf.cdo.util.CDOURIUtil;
+
+import org.eclipse.emf.internal.cdo.CDOViewImpl;
+import org.eclipse.emf.internal.cdo.CDOViewSetImpl;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
@@ -22,20 +29,45 @@ import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
*/
public class CDOResourceFactoryImpl implements Resource.Factory, CDOResourceFactory
{
- // @Singleton
- public static final CDOResourceFactoryImpl INSTANCE = new CDOResourceFactoryImpl();
-
private static final String RESOURCE_SET_CLASS_NAME = ResourceSetImpl.class.getName();
- public CDOResourceFactoryImpl()
+ /**
+ * @since 2.0
+ */
+ private CDOViewSetImpl viewSet;
+
+ /**
+ * @since 2.0
+ */
+ public CDOResourceFactoryImpl(CDOViewSet viewSet)
{
+ this.viewSet = (CDOViewSetImpl)viewSet;
}
public Resource createResource(URI uri)
{
+ // URI can be invalid or incomplete.
+ // Extract repo + resource path and build a new URI.
+
+ String repoUUID = CDOURIUtil.extractRepositoryUUID(uri);
+
+ // repoUUID can be null but can be null
+ CDOViewImpl view = viewSet.resolveUUID(repoUUID);
+
+ // Extract path
+ String path = uri.path();
+
+ // Build a new URI with the view and the path
+ URI newURI = CDOURIUtil.createResourceURI(view, path);
+
CDOResourceImpl resource = (CDOResourceImpl)EresourceFactory.eINSTANCE.createCDOResource();
- resource.setURI(uri);
+ resource.setURI(newURI);
resource.setExisting(isExistingResource());
+
+ if (resource.isExisting())
+ {
+ view.registerProxyResource(resource);
+ }
return resource;
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java
index 5ed1e4a1c2..acfdc2a1d3 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java
@@ -8,25 +8,24 @@
* Contributors:
* Eike Stepper - initial API and implementation
* Simon McDuff - http://bugs.eclipse.org/226778
+ * Simon McDuff - http://bugs.eclipse.org/213402
+ * Simon McDuff - http://bugs.eclipse.org/246705
**************************************************************************/
package org.eclipse.emf.cdo.eresource.impl;
-import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.CDOTransaction;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.eresource.EresourcePackage;
-import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.cdo.util.CDOURIUtil;
+import org.eclipse.emf.cdo.util.LegacySystemNotAvailableException;
import org.eclipse.emf.internal.cdo.CDOObjectImpl;
-import org.eclipse.emf.internal.cdo.CDOViewImpl;
+import org.eclipse.emf.internal.cdo.CDOStateMachine;
import org.eclipse.emf.internal.cdo.InternalCDOObject;
-import org.eclipse.emf.internal.cdo.bundle.OM;
import org.eclipse.emf.internal.cdo.util.FSMUtil;
-import org.eclipse.net4j.util.om.trace.ContextTracer;
-
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.notify.impl.NotificationChainImpl;
@@ -79,16 +78,6 @@ public class CDOResourceImpl extends CDOObjectImpl implements CDOResource
/**
* @ADDED
*/
- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_OBJECT, CDOResourceImpl.class);
-
- /**
- * @ADDED
- */
- private CDOViewImpl view;
-
- /**
- * @ADDED
- */
private boolean existing;
/**
@@ -161,7 +150,7 @@ public class CDOResourceImpl extends CDOObjectImpl implements CDOResource
public void setURI(URI newURI)
{
eSet(EresourcePackage.Literals.CDO_RESOURCE__URI, newURI);
- basicSetPath(CDOUtil.extractResourcePath(newURI));
+ basicSetPath(CDOURIUtil.extractResourcePath(newURI));
}
/**
@@ -306,7 +295,7 @@ public class CDOResourceImpl extends CDOObjectImpl implements CDOResource
*/
public void setPath(String newPath)
{
- setURI(CDOUtil.createResourceURI(newPath));
+ setURI(CDOURIUtil.createResourceURI(cdoView(), newPath));
}
/**
@@ -396,14 +385,14 @@ public class CDOResourceImpl extends CDOObjectImpl implements CDOResource
*/
public void save(Map<?, ?> options) throws IOException
{
- if (view instanceof CDOTransaction)
+ if (cdoView() instanceof CDOTransaction)
{
- CDOTransaction transaction = (CDOTransaction)view;
+ CDOTransaction transaction = (CDOTransaction)cdoView();
transaction.commit();
}
else
{
- throw new IOException("CDO view is read only: " + view);
+ throw new IOException("CDO view is read only: " + cdoView());
}
}
@@ -426,9 +415,14 @@ public class CDOResourceImpl extends CDOObjectImpl implements CDOResource
/**
* @ADDED
*/
- public void delete(Map<?, ?> options) throws IOException
+ public void delete(Map<?, ?> defaultDeleteOptions) throws IOException
{
- throw new UnsupportedOperationException();
+ ResourceSet resourceSet = getResourceSet();
+ if (resourceSet != null)
+ {
+ resourceSet.getResources().remove(this);
+ }
+ cdoView().toTransaction().detach(this);
}
/**
@@ -436,11 +430,8 @@ public class CDOResourceImpl extends CDOObjectImpl implements CDOResource
*/
public void attached(EObject object)
{
- // InternalCDOObject legacy = getLegacyWrapper(object);
- // if (legacy.cdoState() != CDOState.CLEAN)
- // {
- // CDOStateMachine.INSTANCE.attach(legacy, this, view);
- // }
+ InternalCDOObject cdoObject = FSMUtil.adapt(object, cdoView());
+ CDOStateMachine.INSTANCE.attach(cdoObject, cdoView().toTransaction());
}
/**
@@ -448,8 +439,8 @@ public class CDOResourceImpl extends CDOObjectImpl implements CDOResource
*/
public void detached(EObject object)
{
- // InternalCDOObject legacy = getLegacyWrapper(object);
- // CDOStateMachine.INSTANCE.detach(legacy);
+ InternalCDOObject cdoObject = FSMUtil.adapt(object, cdoView());
+ CDOStateMachine.INSTANCE.detach(cdoObject);
}
/**
@@ -503,43 +494,6 @@ public class CDOResourceImpl extends CDOObjectImpl implements CDOResource
/**
* @ADDED
*/
- @Override
- public CDOState cdoState()
- {
- CDOState superState = super.cdoState();
- if (superState == CDOState.TRANSIENT && isExisting())
- {
- return CDOState.PROXY;
- }
-
- return superState;
- }
-
- /**
- * @ADDED
- */
- @Override
- public CDOViewImpl cdoView()
- {
- return view;
- }
-
- /**
- * @ADDED
- */
- public void cdoSetView(CDOViewImpl view)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Setting view: {0}", view);
- }
-
- this.view = view;
- }
-
- /**
- * @ADDED
- */
public boolean isExisting()
{
return existing;
@@ -591,6 +545,34 @@ public class CDOResourceImpl extends CDOObjectImpl implements CDOResource
kind &= ~IS_UNIQUE;
}
}
+
+ @Override
+ public NotificationChain inverseAdd(Object object, NotificationChain notifications)
+ {
+ if (object instanceof InternalCDOObject)
+ {
+ InternalCDOObject eObject = (InternalCDOObject)object;
+ notifications = eObject.eSetResource(CDOResourceImpl.this, notifications);
+ // It is possible that a attached objects gets add to the resource.
+ if (FSMUtil.isTransient(eObject))
+ {
+ attached(eObject);
+ }
+ }
+ else
+ {
+ throw new LegacySystemNotAvailableException();
+ }
+ return notifications;
+ }
+
+ @Override
+ public NotificationChain inverseRemove(Object object, NotificationChain notifications)
+ {
+ InternalEObject eObject = (InternalEObject)object;
+ detached(eObject);
+ return eObject.eSetResource(null, notifications);
+ }
}
/**
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOURIUtil.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOURIUtil.java
new file mode 100644
index 0000000000..66aace87bc
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOURIUtil.java
@@ -0,0 +1,125 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.cdo.util;
+
+import org.eclipse.emf.cdo.CDOSession;
+import org.eclipse.emf.cdo.CDOView;
+import org.eclipse.emf.cdo.common.CDOProtocolConstants;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.internal.common.id.CDOIDExternalImpl;
+
+import org.eclipse.emf.common.util.URI;
+
+/**
+ * @author Simon McDuff
+ * @since 2.0
+ */
+public class CDOURIUtil
+{
+ private static final char SEGMENT_SEPARATOR = '/';
+
+ public static boolean validateURI(URI uri)
+ {
+ if (!CDOProtocolConstants.PROTOCOL_NAME.equals(uri.scheme()))
+ {
+ return false;
+ }
+
+ if (!uri.isHierarchical())
+ {
+ return false;
+ }
+
+ if (!uri.hasAbsolutePath())
+ {
+ return false;
+ }
+ return true;
+ }
+
+ public static String extractResourcePath(URI uri)
+ {
+ if (!validateURI(uri))
+ {
+ return null;
+ }
+ return uri.path();
+ }
+
+ public static String extractRepositoryUUID(URI uri)
+ {
+ if (!validateURI(uri) || !uri.hasAuthority())
+ {
+ return null;
+ }
+ return uri.authority();
+ }
+
+ /**
+ * <p>
+ * cdo://repositoryUUID/path
+ * <p>
+ * The path is added at the end of "cdo://repositoryUUID". If path doesn't start with '/', it will be added
+ * automatically. <br>
+ * e.g.: /resA or resA will give the same result -> cdo://repositoryUUID/resA <br>
+ * authority = repositoryUUID <br>
+ * path = /resA
+ */
+ public static URI createResourceURI(String repositoryUUID, String path)
+ {
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append(CDOProtocolConstants.PROTOCOL_NAME);
+ stringBuilder.append(":");
+
+ if (repositoryUUID != null)
+ {
+ stringBuilder.append("//");
+ stringBuilder.append(repositoryUUID);
+ }
+
+ if (path.charAt(0) != SEGMENT_SEPARATOR)
+ {
+ stringBuilder.append(SEGMENT_SEPARATOR);
+ }
+ stringBuilder.append(path);
+ return URI.createURI(stringBuilder.toString());
+ }
+
+ public static URI createResourceURI(CDOView cdoView, String path)
+ {
+ return createResourceURI(cdoView == null ? null : cdoView.getSession(), path);
+ }
+
+ public static URI createResourceURI(CDOSession cdoSession, String path)
+ {
+ return createResourceURI(cdoSession == null ? null : cdoSession.getRepositoryUUID(), path);
+ }
+
+ /**
+ * Converting temporary CDOID to External CDOID <br>
+ * e.g.: <br>
+ * baseURI = cdo://2a57dfcf-8f97-4d39-8e17-9d99ae5c4b3c/resB#5/2<br>
+ * newCDOID = OID2<br>
+ * return = cdo://2a57dfcf-8f97-4d39-8e17-9d99ae5c4b3c/resB#1/2
+ */
+ public static CDOID convertExternalCDOID(URI baseURI, CDOID newCDOID)
+ {
+ baseURI = baseURI.trimFragment();
+
+ StringBuilder builder = new StringBuilder();
+
+ CDOIDUtil.write(builder, newCDOID);
+ baseURI = baseURI.appendFragment(builder.toString());
+
+ return new CDOIDExternalImpl(baseURI.toString());
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOUtil.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOUtil.java
index 75a89a7690..c1a6284b7e 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOUtil.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOUtil.java
@@ -7,23 +7,28 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.cdo.util;
import org.eclipse.emf.cdo.CDOSessionConfiguration;
import org.eclipse.emf.cdo.CDOView;
-import org.eclipse.emf.cdo.common.CDOProtocolConstants;
-import org.eclipse.emf.cdo.eresource.CDOResourceFactory;
+import org.eclipse.emf.cdo.CDOViewSet;
+import org.eclipse.emf.cdo.CDOXATransaction;
import org.eclipse.emf.internal.cdo.CDOSessionConfigurationImpl;
import org.eclipse.emf.internal.cdo.CDOStateMachine;
import org.eclipse.emf.internal.cdo.CDOViewImpl;
+import org.eclipse.emf.internal.cdo.CDOViewSetImpl;
+import org.eclipse.emf.internal.cdo.CDOXATransactionImpl;
import org.eclipse.emf.internal.cdo.InternalCDOObject;
import org.eclipse.emf.internal.cdo.LegacySupportEnabler;
import org.eclipse.emf.internal.cdo.protocol.CDOClientProtocolFactory;
import org.eclipse.emf.internal.cdo.util.CDOPackageRegistryImpl;
import org.eclipse.emf.internal.cdo.util.FSMUtil;
+import org.eclipse.emf.internal.cdo.util.ProxyResolverURIResourceMap;
+import org.eclipse.net4j.util.ImplementationError;
import org.eclipse.net4j.util.container.IManagedContainer;
import org.eclipse.emf.common.notify.Adapter;
@@ -36,8 +41,9 @@ import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EcoreFactory;
+import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.emf.ecore.resource.Resource.Factory.Registry;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import java.util.Iterator;
import java.util.Map;
@@ -74,62 +80,95 @@ public final class CDOUtil
return new CDOPackageRegistryImpl.DemandPopulating();
}
- public static CDOView getView(ResourceSet resourceSet)
+ /**
+ * @since 2.0
+ */
+ public static CDOXATransaction createXATransaction(CDOViewSet viewSet)
{
- EList<Adapter> adapters = resourceSet.eAdapters();
- for (Adapter adapter : adapters)
+ CDOXATransaction xaTransaction = new CDOXATransactionImpl();
+ if (viewSet != null)
{
- if (adapter instanceof CDOView)
- {
- return (CDOView)adapter;
- }
+ xaTransaction.add(viewSet);
}
-
- return null;
+ return xaTransaction;
}
- public static void prepareResourceSet(ResourceSet resourceSet)
+ /**
+ * @since 2.0
+ */
+ public static CDOXATransaction createXATransaction()
{
- CDOResourceFactory factory = CDOResourceFactory.INSTANCE;
- Registry registry = resourceSet.getResourceFactoryRegistry();
- Map<String, Object> map = registry.getProtocolToFactoryMap();
- map.put(CDOProtocolConstants.PROTOCOL_NAME, factory);
+ return createXATransaction(null);
}
- public static void prepareContainer(IManagedContainer container, boolean legacySupportEnabled)
+ /**
+ * @since 2.0
+ */
+ public static CDOXATransaction getXATransaction(CDOViewSet viewSet)
{
- container.registerFactory(new CDOClientProtocolFactory());
- container.addPostProcessor(new LegacySupportEnabler(legacySupportEnabled));
+ EList<Adapter> adapters = viewSet.eAdapters();
+ for (Adapter adapter : adapters)
+ {
+ if (adapter instanceof CDOXATransactionImpl.CDOXAInternalAdapter)
+ {
+ return ((CDOXATransactionImpl.CDOXAInternalAdapter)adapter).getCDOXA();
+ }
+ }
+ return null;
}
- public static String extractResourcePath(URI uri)
+ /**
+ * @since 2.0
+ */
+ public static CDOViewSet getViewSet(ResourceSet resourceSet)
{
- if (!CDOProtocolConstants.PROTOCOL_NAME.equals(uri.scheme()))
+ EList<Adapter> adapters = resourceSet.eAdapters();
+ for (Adapter adapter : adapters)
{
- return null;
+ if (adapter instanceof CDOViewSet)
+ {
+ return (CDOViewSet)adapter;
+ }
}
+ return null;
+ }
- if (uri.hasAuthority())
- {
- return null;
- }
+ /**
+ * @since 2.0
+ */
+ public static CDOViewSet prepareResourceSet(ResourceSet resourceSet)
+ {
+ CDOViewSetImpl viewSet = null;
- if (!uri.isHierarchical())
+ synchronized (resourceSet)
{
- return null;
- }
+ viewSet = (CDOViewSetImpl)getViewSet(resourceSet);
- if (!uri.hasAbsolutePath())
- {
- return null;
+ if (viewSet == null)
+ {
+ if (resourceSet instanceof ResourceSetImpl)
+ {
+ Map<URI, Resource> resourceMap = null;
+ ResourceSetImpl rs = (ResourceSetImpl)resourceSet;
+ resourceMap = rs.getURIResourceMap();
+ rs.setURIResourceMap(new ProxyResolverURIResourceMap(null, resourceMap));
+ }
+ else
+ {
+ throw new ImplementationError("Not a " + ResourceSetImpl.class.getName() + ": "
+ + resourceSet.getClass().getName());
+ }
+ viewSet = new CDOViewSetImpl();
+ resourceSet.eAdapters().add(viewSet);
+ }
}
-
- return uri.path();
+ return viewSet;
}
- public static URI createResourceURI(String path)
+ public static void prepareContainer(IManagedContainer container, boolean legacySupportEnabled)
{
- return URI.createURI(CDOProtocolConstants.PROTOCOL_NAME + ":" + path);
+ container.registerFactory(new CDOClientProtocolFactory());
+ container.addPostProcessor(new LegacySupportEnabler(legacySupportEnabled));
}
public static EPackage createEPackage(String name, String nsPrefix, String nsURI)
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOAbstractSavepoint.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOAbstractSavepoint.java
new file mode 100644
index 0000000000..f977c45d62
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOAbstractSavepoint.java
@@ -0,0 +1,92 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo;
+
+import org.eclipse.emf.cdo.CDOSavepoint;
+import org.eclipse.emf.cdo.CDOUserTransaction;
+
+/**
+ * @author Simon McDuff
+ * @since 2.0
+ */
+public abstract class CDOAbstractSavepoint implements CDOSavepoint
+{
+ private CDOUserTransaction userTransaction;
+
+ private CDOAbstractSavepoint previousSavepoint;
+
+ private CDOAbstractSavepoint nextSavepoint;
+
+ public CDOAbstractSavepoint(CDOUserTransaction transaction, CDOAbstractSavepoint lastSavepoint)
+ {
+ userTransaction = transaction;
+ previousSavepoint = lastSavepoint;
+ if (previousSavepoint != null)
+ {
+ previousSavepoint.setNextSavepoint(this);
+ }
+ }
+
+ public void setPreviousSavepoint(CDOAbstractSavepoint previousSavepoint)
+ {
+ this.previousSavepoint = previousSavepoint;
+ }
+
+ public void setNextSavepoint(CDOAbstractSavepoint nextSavepoint)
+ {
+ this.nextSavepoint = nextSavepoint;
+ }
+
+ public CDOSavepoint getNextSavepoint()
+ {
+ return nextSavepoint;
+ }
+
+ public CDOSavepoint getPreviousSavepoint()
+ {
+ return previousSavepoint;
+ }
+
+ public CDOAbstractSavepoint getFirstSavePoint()
+ {
+ return previousSavepoint != null ? previousSavepoint.getFirstSavePoint() : this;
+ }
+
+ public CDOUserTransaction getUserTransaction()
+ {
+ return userTransaction;
+ }
+
+ public boolean isValid()
+ {
+ CDOSavepoint lastSavepoint = getUserTransaction().getLastSavepoint();
+ for (CDOSavepoint savepoint = lastSavepoint; savepoint != null; savepoint = savepoint.getPreviousSavepoint())
+ {
+ if (savepoint == this)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public void rollback(boolean remote)
+ {
+ getUserTransaction().rollback(this, remote);
+ }
+
+ public void rollback()
+ {
+ getUserTransaction().rollback(this);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOCallbackImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOCallbackImpl.java
index 061ee9d979..fe83b1433f 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOCallbackImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOCallbackImpl.java
@@ -117,7 +117,7 @@ public class CDOCallbackImpl extends CDOLegacyImpl implements CDOCallback
if (((InternalEObject)instance).eDeliver())
{
InternalCDOObject object = FSMUtil.adapt(instance, view);
- CDOStateMachine.INSTANCE.attach(object, cdoResource(), view);
+ CDOStateMachine.INSTANCE.attach(object, view.toTransaction());
}
}
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOCommitContext.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOCommitContext.java
new file mode 100644
index 0000000000..4425c3009c
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOCommitContext.java
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo;
+
+import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.model.CDOPackage;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.eresource.CDOResource;
+
+import org.eclipse.emf.internal.cdo.protocol.CommitTransactionResult;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Provides a context for a commit operation.
+ *
+ * @author Simon McDuff
+ * @since 2.0
+ */
+public interface CDOCommitContext
+{
+ public InternalCDOTransaction getTransaction();
+
+ public void preCommit();
+
+ public void postCommit(CommitTransactionResult result);
+
+ public List<CDOPackage> getNewPackages();
+
+ public Map<CDOID, CDOResource> getNewResources();
+
+ public Map<CDOID, CDOObject> getNewObjects();
+
+ public Map<CDOID, CDOObject> getDirtyObjects();
+
+ public Set<CDOID> getDetachedObjects();
+
+ public Map<CDOID, CDORevisionDelta> getRevisionDeltas();
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOLegacyImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOLegacyImpl.java
index e6c5a20e0a..e13f8fade3 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOLegacyImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOLegacyImpl.java
@@ -91,18 +91,6 @@ public abstract class CDOLegacyImpl extends CDOWrapperImpl implements Adapter.In
return CDOObjectImpl.getCDOClass(this);
}
- @Override
- public CDOViewImpl cdoView()
- {
- // TODO Why is this lazy?
- if (view == null)
- {
- view = CDOObjectImpl.getCDOView(this);
- }
-
- return view;
- }
-
public void cdoReload()
{
CDOStateMachine.INSTANCE.reload(this);
@@ -358,19 +346,20 @@ public abstract class CDOLegacyImpl extends CDOWrapperImpl implements Adapter.In
protected void transferContainmentToInstance(CDOViewImpl view)
{
- CDOID containerID = revision.getContainerID();
- if (containerID.isNull())
- {
- CDOID resourceID = revision.getResourceID();
- Resource.Internal resource = (Resource.Internal)view.getObject(resourceID);
- transferResourceToInstance(resource);
- }
- else
- {
- int containingFeatureID = revision.getContainingFeatureID();
- InternalEObject container = convertPotentialID(view, containerID);
- ((BasicEObjectImpl)instance).eBasicSetContainer(container, containingFeatureID, null);
- }
+ // Not supported anymore
+ // Object containerID = revision.getContainerID();
+ // if (containerID.isNull())
+ // {
+ // CDOID resourceID = revision.getResourceID();
+ // Resource.Internal resource = (Resource.Internal)view.getObject(resourceID);
+ // transferResourceToInstance(resource);
+ // }
+ // else
+ // {
+ // int containingFeatureID = revision.getContainingFeatureID();
+ // InternalEObject container = convertPotentialID(view, containerID);
+ // ((BasicEObjectImpl)instance).eBasicSetContainer(container, containingFeatureID, null);
+ // }
}
public void transferResourceToInstance(Resource.Internal resource)
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java
index 5542893099..68c50117ac 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java
@@ -8,10 +8,12 @@
* Contributors:
* Eike Stepper - initial API and implementation
* Simon McDuff - http://bugs.eclipse.org/233490
+ * Eike Stepper & Simon McDuff - http://bugs.eclipse.org/204890
+ * Simon McDuff - http://bugs.eclipse.org/246705
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.internal.cdo;
-import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.CDOView;
import org.eclipse.emf.cdo.common.id.CDOID;
@@ -32,6 +34,8 @@ import org.eclipse.net4j.util.ImplementationError;
import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.BasicEMap;
import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.EList;
@@ -41,6 +45,8 @@ import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.impl.BasicEObjectImpl;
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.impl.EStoreEObjectImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.Resource.Internal;
@@ -50,6 +56,7 @@ import org.eclipse.emf.ecore.util.EcoreEList;
import org.eclipse.emf.ecore.util.EcoreEMap;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.ecore.util.InternalEList;
import java.util.Collection;
import java.util.Iterator;
@@ -67,6 +74,8 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec
private CDOState state;
+ private CDOViewImpl cdoView;
+
private CDOResourceImpl resource;
private InternalCDORevision revision;
@@ -99,7 +108,7 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec
public CDOViewImpl cdoView()
{
- return getCDOView(this);
+ return cdoView;
}
public CDOResourceImpl cdoResource()
@@ -168,11 +177,7 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec
public void cdoInternalSetView(CDOView view)
{
CDOViewImpl impl = (CDOViewImpl)view;
- if (this instanceof CDOResourceImpl)
- {
- ((CDOResourceImpl)this).cdoSetView(impl);
- }
-
+ cdoView = impl;
eSetStore(impl.getStore());
}
@@ -204,14 +209,18 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec
}
CDOViewImpl view = cdoView();
- revision.setContainerID(eContainer == null ? CDOID.NULL : ((CDOObjectImpl)eContainer).cdoID());
+ revision.setContainerID(eContainer == null ? CDOID.NULL : cdoView().convertObjectToID(eContainer, true));
revision.setContainingFeatureID(eContainerFeatureID);
-
- if (eSettings == null)
+ Resource directResource = eDirectResource();
+ if (directResource instanceof CDOResource)
{
- eSettings();
+ CDOResource cdoResource = (CDOResource)directResource;
+ cdoInternalSetResource(cdoResource);
+ revision.setResourceID(cdoResource.cdoID());
}
+ eSettings();
+
EClass eClass = eClass();
for (int i = 0; i < eClass.getFeatureCount(); i++)
{
@@ -257,7 +266,7 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec
{
if (cdoFeature.isReference())
{
- value = view.convertObjectToID(value);
+ value = view.convertObjectToID(value, true);
}
revision.add(cdoFeature, index++, value);
@@ -268,7 +277,7 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec
{
if (cdoFeature.isReference())
{
- setting = view.convertObjectToID(setting);
+ setting = view.convertObjectToID(setting, true);
}
else
{
@@ -302,22 +311,15 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec
eContainer = null;
eContainerFeatureID = 0;
- if (eSettings == null)
- {
- eSettings();
- }
+ eSettings();
EClass eClass = eClass();
for (int i = 0; i < eClass.getFeatureCount(); i++)
{
- Object setting = eSettings[i];
- if (setting != null)
+ EStructuralFeature eFeature = cdoInternalDynamicFeature(i);
+ if (!eFeature.isTransient())
{
- EStructuralFeature eFeature = cdoInternalDynamicFeature(i);
- if (!eFeature.isTransient())
- {
- depopulateRevisionFeature(view, revision, eFeature, eSettings, i);
- }
+ depopulateRevisionFeature(view, revision, eFeature, eSettings, i);
}
}
}
@@ -336,13 +338,13 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec
if (cdoFeature.isMany())
{
eSettings[i] = null;
- EList<Object> setting = (EList<Object>)super.dynamicGet(eFeature.getFeatureID());
- EList<Object> list = (EList<Object>)revision.getList(cdoFeature);
+ List<Object> setting = (List<Object>)super.dynamicGet(eFeature.getFeatureID());
+ List<Object> list = revision.getList(cdoFeature);
for (Object value : list)
{
if (isReference)
{
- value = view.getObject((CDOID)value, true);
+ value = view.convertIDToObject(value);
}
setting.add(value);
@@ -353,7 +355,7 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec
Object value = revision.getValue(cdoFeature);
if (isReference)
{
- value = view.getObject((CDOID)value, true);
+ value = view.convertIDToObject(value);
}
else if (cdoFeature.getType() == CDOType.CUSTOM)
{
@@ -489,11 +491,36 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec
@Override
protected void eSetDirectResource(Internal resource)
{
- super.eSetDirectResource(resource);
- if (resource instanceof CDOResourceImpl)
+ if (FSMUtil.isTransient(this))
{
+ super.eSetDirectResource(resource);
+ }
+ else if (resource instanceof CDOResourceImpl || resource == null)
+ {
+
this.resource = (CDOResourceImpl)resource;
+ getStore().setContainer(this, cdoResource(), eInternalContainer(), eContainerFeatureID());
+ }
+ else
+ {
+ throw new IllegalArgumentException("Resource needs to be an instanceof CDOResourceImpl");
+ }
+ }
+
+ @Override
+ public Internal eDirectResource()
+ {
+ if (this instanceof Internal)
+ {
+ return (Internal)this;
+ }
+
+ if (FSMUtil.isTransient(this))
+ {
+ return super.eDirectResource();
}
+
+ return cdoResource();
}
/**
@@ -606,47 +633,169 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec
return getStore().getContainingFeatureID(this);
}
+ /**
+ * Code took from {@link BasicEObjectImpl#eBasicSetContainer} and modify it to detect when object are moved in the
+ * same context.
+ */
@Override
- protected void eBasicSetContainer(InternalEObject newContainer, int newContainerFeatureID)
+ public NotificationChain eBasicSetContainer(InternalEObject newContainer, int newContainerFeatureID,
+ NotificationChain msgs)
{
- if (TRACER.isEnabled())
+ InternalEObject oldContainer = eInternalContainer();
+ Resource.Internal oldResource = eDirectResource();
+ Resource.Internal newResource = null;
+ if (oldResource != null)
{
- TRACER.format("Setting container: {0}, featureID={1}", newContainer, newContainerFeatureID);
+ if (newContainer != null && !eContainmentFeature(this, newContainer, newContainerFeatureID).isResolveProxies())
+ {
+ msgs = ((InternalEList<?>)oldResource.getContents()).basicRemove(this, msgs);
+ eSetDirectResource(null);
+ newResource = newContainer.eInternalResource();
+ }
+ else
+ {
+ oldResource = null;
+ }
}
+ else
+ {
+ if (oldContainer != null)
+ {
+ oldResource = oldContainer.eInternalResource();
+ }
+ if (newContainer != null)
+ {
+ newResource = newContainer.eInternalResource();
+ }
+ }
+ CDOView oldView = cdoView;
+ CDOView newView = newResource != null && newResource instanceof CDOResource ? ((CDOResource)newResource).cdoView()
+ : null;
- if (FSMUtil.isTransient(this))
+ boolean moved = oldView != null && oldView == newView;
+
+ if (!moved && oldResource != null)
{
- super.eBasicSetContainer(newContainer, newContainerFeatureID);
+ oldResource.detached(this);
}
- else
+
+ int oldContainerFeatureID = eContainerFeatureID();
+ eBasicSetContainer(newContainer, newContainerFeatureID);
+
+ if (!moved && oldResource != newResource && newResource != null)
+ {
+ newResource.attached(this);
+ }
+
+ if (eNotificationRequired())
{
- CDOResource newResource = null;
- if (newContainer instanceof CDOObject)
+ if (oldContainer != null && oldContainerFeatureID >= 0 && oldContainerFeatureID != newContainerFeatureID)
{
- newResource = ((CDOObject)newContainer).cdoResource();
+ ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, oldContainerFeatureID,
+ oldContainer, null);
+ if (msgs == null)
+ {
+ msgs = notification;
+ }
+ else
+ {
+ msgs.add(notification);
+ }
+ }
+ if (newContainerFeatureID >= 0)
+ {
+ ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, newContainerFeatureID,
+ oldContainerFeatureID == newContainerFeatureID ? oldContainer : null, newContainer);
+ if (msgs == null)
+ {
+ msgs = notification;
+ }
+ else
+ {
+ msgs.add(notification);
+ }
}
+ }
+ return msgs;
+ }
- // Delegate to CDOStore
- getStore().setContainer(this, newResource, newContainer, newContainerFeatureID);
+ /**
+ * Code took from {@link BasicEObjectImpl#eSetResource} and modify it to detect when object are moved in the same
+ * context.
+ */
+ @Override
+ public NotificationChain eSetResource(Resource.Internal resource, NotificationChain notifications)
+ {
+ Resource.Internal oldResource = eDirectResource();
+
+ CDOView oldView = cdoView;
+ CDOView newView = resource != null && resource instanceof CDOResource ? ((CDOResource)resource).cdoView() : null;
- resource = (CDOResourceImpl)newResource;
- if (newContainer instanceof Resource.Internal)
+ boolean isSameView = oldView != null && oldView == newView;
+
+ if (oldResource != null)
+ {
+ notifications = ((InternalEList<?>)oldResource.getContents()).basicRemove(this, notifications);
+
+ // When setting the resource to null we assume that detach has already been called in the resource implementation
+ //
+
+ if (!isSameView && resource != null)
{
- eSetDirectResource((Resource.Internal)newContainer);
+ oldResource.detached(this);
}
}
+
+ InternalEObject oldContainer = eInternalContainer();
+ if (oldContainer != null && !isSameView)
+ {
+ if (eContainmentFeature().isResolveProxies())
+ {
+ Resource.Internal oldContainerResource = oldContainer.eInternalResource();
+ if (oldContainerResource != null)
+ {
+ // If we're not setting a new resource, attach it to the old container's resource.
+ if (resource == null)
+ {
+ oldContainerResource.attached(this);
+ }
+ // If we didn't detach it from an old resource already, detach it from the old container's resource.
+ //
+ else if (oldResource == null)
+ {
+ oldContainerResource.detached(this);
+ }
+ }
+ }
+ else
+ {
+ notifications = eBasicRemoveFromContainer(notifications);
+ notifications = eBasicSetContainer(null, -1, notifications);
+ }
+ }
+
+ eSetDirectResource(resource);
+
+ return notifications;
}
@Override
- public Resource eResource()
+ protected void eBasicSetContainer(InternalEObject newEContainer, int newContainerFeatureID)
{
- Resource resource = cdoResource();
- if (resource == null && FSMUtil.isTransient(this))
+ if (TRACER.isEnabled())
{
- resource = super.eResource();
+ TRACER.format("Setting container: {0}, featureID={1}", newEContainer, newContainerFeatureID);
}
- return resource;
+ if (FSMUtil.isTransient(this))
+ {
+ super.eBasicSetContainer(newEContainer, newContainerFeatureID);
+
+ }
+ else
+ {
+ getStore().setContainer(this, cdoResource(), newEContainer, newContainerFeatureID);
+ }
}
/**
@@ -676,15 +825,9 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec
return ModelUtil.getCDOClass(cdoObject.eClass(), packageManager);
}
- static CDOViewImpl getCDOView(InternalCDOObject cdoObject)
- {
- CDOResource resource = cdoObject.cdoResource();
- return resource != null ? (CDOViewImpl)cdoObject.cdoResource().cdoView() : null;
- }
-
private CDOStore getStore()
{
- return cdoView().getStore();
+ return (CDOStore)eStore();
}
/**
@@ -702,12 +845,6 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec
}
@Override
- protected boolean hasProxies()
- {
- return true;
- }
-
- @Override
protected List<E> delegateList()
{
throw new UnsupportedOperationException();
@@ -916,12 +1053,6 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec
}
@Override
- protected boolean hasProxies()
- {
- return true;
- }
-
- @Override
protected List<FeatureMap.Entry> delegateList()
{
throw new UnsupportedOperationException();
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSavepointImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSavepointImpl.java
index e4c232d47a..69ceb8d386 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSavepointImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSavepointImpl.java
@@ -8,19 +8,27 @@
* Contributors:
* Simon McDuff - initial API and implementation
* Eike Stepper - maintenance
+ * Simon McDuff - http://bugs.eclipse.org/204890
**************************************************************************/
package org.eclipse.emf.internal.cdo;
import org.eclipse.emf.cdo.CDOObject;
-import org.eclipse.emf.cdo.CDOSavepoint;
-import org.eclipse.emf.cdo.CDOTransaction;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.internal.common.revision.delta.CDORevisionDeltaImpl;
+import org.eclipse.net4j.util.collection.MultiMap;
+
+import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -28,10 +36,8 @@ import java.util.concurrent.ConcurrentMap;
* @author Simon McDuff
* @since 2.0
*/
-public class CDOSavepointImpl implements CDOSavepoint
+public class CDOSavepointImpl extends CDOAbstractSavepoint
{
- private CDOTransactionImpl transaction;
-
private Map<CDOID, CDOResource> newResources = new HashMap<CDOID, CDOResource>();
private Map<CDOID, CDOObject> newObjects = new HashMap<CDOID, CDOObject>();
@@ -40,22 +46,43 @@ public class CDOSavepointImpl implements CDOSavepoint
private Map<CDOID, CDOObject> dirtyObjects = new HashMap<CDOID, CDOObject>();
- private ConcurrentMap<CDOID, CDORevisionDelta> revisionDeltas = new ConcurrentHashMap<CDOID, CDORevisionDelta>();
+ private Set<CDOID> detachedObjects = new HashSet<CDOID>()
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public boolean add(CDOID key)
+ {
+ sharedDetachedObjects.add(key);
+ dirtyObjects.remove(key);
+ baseNewObjects.remove(key);
+ newObjects.remove(key);
+ newResources.remove(key);
+ return super.add(key);
+ }
+ };
- private CDOSavepointImpl previousSavepoint;
+ private ConcurrentMap<CDOID, CDORevisionDelta> revisionDeltas = new ConcurrentHashMap<CDOID, CDORevisionDelta>();
- private CDOSavepointImpl nextSavepoint;
+ /**
+ * Contains all persistent CDOIDs that were removed. The same instance is shared between all save points that belong
+ * to the same transaction.
+ */
+ private Set<CDOID> sharedDetachedObjects;
private boolean isDirty;
public CDOSavepointImpl(CDOTransactionImpl transaction, CDOSavepointImpl lastSavepoint)
{
- this.transaction = transaction;
+ super(transaction, lastSavepoint);
isDirty = transaction.isDirty();
- previousSavepoint = lastSavepoint;
- if (previousSavepoint != null)
+ if (getPreviousSavepoint() == null)
+ {
+ sharedDetachedObjects = new HashSet<CDOID>();
+ }
+ else
{
- previousSavepoint.setNextSavepoint(this);
+ sharedDetachedObjects = lastSavepoint.getSharedDetachedObjects();
}
}
@@ -66,6 +93,7 @@ public class CDOSavepointImpl implements CDOSavepoint
dirtyObjects.clear();
revisionDeltas.clear();
baseNewObjects.clear();
+ detachedObjects.clear();
}
public boolean isDirty()
@@ -83,11 +111,21 @@ public class CDOSavepointImpl implements CDOSavepoint
return newObjects;
}
+ public Set<CDOID> getDetachedObjects()
+ {
+ return detachedObjects;
+ }
+
public Map<CDOID, CDOObject> getDirtyObjects()
{
return dirtyObjects;
}
+ public Set<CDOID> getSharedDetachedObjects()
+ {
+ return sharedDetachedObjects;
+ }
+
public ConcurrentMap<CDOID, CDORevisionDelta> getRevisionDeltas()
{
return revisionDeltas;
@@ -98,52 +136,217 @@ public class CDOSavepointImpl implements CDOSavepoint
return baseNewObjects;
}
- public CDOSavepointImpl getPreviousSavepoint()
+ /**
+ * Return the list of new objects from this point.
+ */
+ public Map<CDOID, CDOObject> getAllDirtyObjects()
{
- return previousSavepoint;
- }
+ if (getPreviousSavepoint() == null)
+ {
+ return getDirtyObjects();
+ }
- public CDOSavepointImpl getNextSavepoint()
- {
- return nextSavepoint;
- }
+ MultiMap.ListBased<CDOID, CDOObject> dirtyObjects = new MultiMap.ListBased<CDOID, CDOObject>();
+ for (CDOSavepointImpl savepoint = this; savepoint != null; savepoint = savepoint.getPreviousSavepoint())
+ {
+ dirtyObjects.getDelegates().add(savepoint.getDirtyObjects());
+ }
- public void setPreviousSavepoint(CDOSavepointImpl previousSavepoint)
- {
- this.previousSavepoint = previousSavepoint;
+ return dirtyObjects;
}
- public void setNextSavepoint(CDOSavepointImpl nextSavepoint)
+ /**
+ * Return the list of new objects from this point without objects that are removed.
+ */
+ public Map<CDOID, CDOObject> getAllNewObjects()
{
- this.nextSavepoint = nextSavepoint;
+ if (getPreviousSavepoint() == null)
+ {
+ return Collections.unmodifiableMap(getNewObjects());
+ }
+
+ if (getSharedDetachedObjects().size() == 0)
+ {
+ MultiMap.ListBased<CDOID, CDOObject> newObjects = new MultiMap.ListBased<CDOID, CDOObject>();
+ for (CDOSavepointImpl savepoint = this; savepoint != null; savepoint = savepoint.getPreviousSavepoint())
+ {
+ newObjects.getDelegates().add(savepoint.getNewObjects());
+ }
+
+ return newObjects;
+ }
+
+ Map<CDOID, CDOObject> newObjects = new HashMap<CDOID, CDOObject>();
+ for (CDOSavepointImpl savepoint = this; savepoint != null; savepoint = savepoint.getPreviousSavepoint())
+ {
+ for (CDOObject object : savepoint.getNewObjects().values())
+ {
+ if (!getSharedDetachedObjects().contains(object.cdoID()))
+ {
+ newObjects.put(object.cdoID(), object);
+ }
+ }
+ }
+
+ return newObjects;
}
- public CDOTransaction getTransaction()
+ /**
+ * Return the list of new resources from this point without objects that are removed.
+ */
+ public Map<CDOID, CDOResource> getAllNewResources()
{
- return transaction;
+ if (getPreviousSavepoint() == null)
+ {
+ return Collections.unmodifiableMap(getNewResources());
+ }
+
+ if (getSharedDetachedObjects().size() == 0)
+ {
+ MultiMap.ListBased<CDOID, CDOResource> newResources = new MultiMap.ListBased<CDOID, CDOResource>();
+ for (CDOSavepointImpl savepoint = this; savepoint != null; savepoint = savepoint.getPreviousSavepoint())
+ {
+ newResources.getDelegates().add(savepoint.getNewResources());
+ }
+
+ return newResources;
+ }
+
+ Map<CDOID, CDOResource> newResources = new HashMap<CDOID, CDOResource>();
+ for (CDOSavepointImpl savepoint = this; savepoint != null; savepoint = savepoint.getPreviousSavepoint())
+ {
+ for (CDOResource resource : savepoint.getNewResources().values())
+ {
+ if (!sharedDetachedObjects.contains(resource.cdoID()))
+ {
+ newResources.put(resource.cdoID(), resource);
+ }
+ }
+ }
+
+ return newResources;
}
- public void rollback(boolean remote)
+ /**
+ * @since 2.0
+ */
+ public Map<CDOID, CDORevision> getAllBaseNewObjects()
{
- getTransaction().rollback(this, remote);
+ if (getPreviousSavepoint() == null)
+ {
+ return Collections.unmodifiableMap(getBaseNewObjects());
+ }
+
+ MultiMap.ListBased<CDOID, CDORevision> newObjects = new MultiMap.ListBased<CDOID, CDORevision>();
+ for (CDOSavepointImpl savepoint = this; savepoint != null; savepoint = savepoint.getPreviousSavepoint())
+ {
+ newObjects.getDelegates().add(savepoint.getBaseNewObjects());
+ }
+
+ return newObjects;
}
- public void rollback()
+ /**
+ * Return the list of all deltas without objects that are removed.
+ */
+ public Map<CDOID, CDORevisionDelta> getAllRevisionDeltas()
{
- getTransaction().rollback(this);
+ if (getPreviousSavepoint() == null)
+ {
+ return Collections.unmodifiableMap(getRevisionDeltas());
+ }
+
+ // We need to combined the result for all delta in different Savepoint
+ Map<CDOID, CDORevisionDelta> revisionDeltas = new ConcurrentHashMap<CDOID, CDORevisionDelta>();
+ for (CDOSavepointImpl savepoint = (CDOSavepointImpl)getFirstSavePoint(); savepoint != null; savepoint = savepoint
+ .getNextSavepoint())
+ {
+ for (Entry<CDOID, CDORevisionDelta> entry : savepoint.getRevisionDeltas().entrySet())
+ {
+ // Skipping temporary
+ if (entry.getKey().isTemporary() || detachedObjects.contains(entry.getKey()))
+ {
+ continue;
+ }
+
+ CDORevisionDeltaImpl revisionDelta = (CDORevisionDeltaImpl)revisionDeltas.get(entry.getKey());
+ if (revisionDelta == null)
+ {
+ revisionDeltas.put(entry.getKey(), entry.getValue());
+ }
+ else
+ {
+ for (CDOFeatureDelta delta : entry.getValue().getFeatureDeltas())
+ {
+ if (delta instanceof CDOListFeatureDelta)
+ {
+ for (CDOFeatureDelta subDelta : ((CDOListFeatureDelta)delta).getListChanges())
+ {
+ revisionDelta.addFeatureDelta(subDelta);
+ }
+ }
+ else
+ {
+ revisionDelta.addFeatureDelta(delta);
+ }
+ }
+ }
+ }
+ }
+
+ return revisionDeltas;
}
- public boolean isValid()
+ public Set<CDOID> getAllDetachedObjects()
{
- CDOSavepoint lastSavepoint = getTransaction().getLastSavepoint();
- for (CDOSavepoint savepoint = lastSavepoint; savepoint != null; savepoint = savepoint.getPreviousSavepoint())
+ if (getPreviousSavepoint() == null)
+ {
+ return Collections.unmodifiableSet(getDetachedObjects());
+ }
+
+ Set<CDOID> detachedObjects = new HashSet<CDOID>();
+ for (CDOSavepointImpl savepoint = this; savepoint != null; savepoint = savepoint.getPreviousSavepoint())
{
- if (savepoint == this)
+ for (CDOID id : savepoint.getDetachedObjects())
{
- return true;
+ detachedObjects.add(id);
}
}
- return false;
+ return detachedObjects;
+ }
+
+ @Override
+ public CDOSavepointImpl getPreviousSavepoint()
+ {
+ return (CDOSavepointImpl)super.getPreviousSavepoint();
+ }
+
+ @Override
+ public CDOSavepointImpl getNextSavepoint()
+ {
+ return (CDOSavepointImpl)super.getNextSavepoint();
+ }
+
+ public void setPreviousSavepoint(CDOSavepointImpl previousSavepoint)
+ {
+ super.setPreviousSavepoint(previousSavepoint);
+ }
+
+ public void setNextSavepoint(CDOSavepointImpl nextSavepoint)
+ {
+ super.setNextSavepoint(nextSavepoint);
+ }
+
+ @Override
+ public void rollback(boolean remote)
+ {
+ getUserTransaction().rollback(this, remote);
+ }
+
+ @Override
+ public void rollback()
+ {
+ getUserTransaction().rollback(this);
}
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java
index fb5f8226aa..df5941873e 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java
@@ -10,12 +10,14 @@
* Simon McDuff - http://bugs.eclipse.org/226778
* Simon McDuff - http://bugs.eclipse.org/230832
* Simon McDuff - http://bugs.eclipse.org/233490
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.internal.cdo;
import org.eclipse.emf.cdo.CDOSession;
import org.eclipse.emf.cdo.CDOSessionInvalidationEvent;
import org.eclipse.emf.cdo.CDOView;
+import org.eclipse.emf.cdo.CDOViewSet;
import org.eclipse.emf.cdo.common.CDOProtocolConstants;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDAndVersion;
@@ -24,6 +26,7 @@ import org.eclipse.emf.cdo.common.id.CDOIDMetaRange;
import org.eclipse.emf.cdo.common.id.CDOIDObject;
import org.eclipse.emf.cdo.common.id.CDOIDObjectFactory;
import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.common.id.CDOIDTempMeta;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.model.CDOClass;
import org.eclipse.emf.cdo.common.model.CDOClassRef;
@@ -48,7 +51,6 @@ import org.eclipse.emf.internal.cdo.protocol.ViewsChangedRequest;
import org.eclipse.emf.internal.cdo.util.CDOPackageRegistryImpl;
import org.eclipse.emf.internal.cdo.util.FSMUtil;
import org.eclipse.emf.internal.cdo.util.ModelUtil;
-import org.eclipse.emf.internal.cdo.util.ProxyResolverURIResourceMap;
import org.eclipse.net4j.channel.IChannel;
import org.eclipse.net4j.connector.IConnector;
@@ -71,12 +73,9 @@ import org.eclipse.net4j.util.lifecycle.ILifecycle;
import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter;
import org.eclipse.net4j.util.om.trace.ContextTracer;
-import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.InternalEObject;
-import org.eclipse.emf.ecore.impl.EPackageRegistryImpl;
-import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
@@ -151,7 +150,7 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD
private ConcurrentMap<CDOID, CDOClass> types = new ConcurrentHashMap<CDOID, CDOClass>();
- private Map<ResourceSet, CDOViewImpl> views = new HashMap<ResourceSet, CDOViewImpl>();
+ private Set<CDOViewImpl> views = new HashSet<CDOViewImpl>();
@ExcludeFromDump
private transient Map<CDOID, InternalEObject> idToMetaInstanceMap = new HashMap<CDOID, InternalEObject>();
@@ -384,13 +383,10 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD
public CDOViewImpl[] getViews()
{
- Collection<CDOViewImpl> values;
synchronized (views)
{
- values = views.values();
+ return views.toArray(new CDOViewImpl[views.size()]);
}
-
- return values.toArray(new CDOViewImpl[values.size()]);
}
public CDOView[] getElements()
@@ -406,10 +402,11 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD
public void viewDetached(CDOViewImpl view)
{
- ResourceSet resourceSet = view.getResourceSet();
+ // Detach viewset from the view
+ ((CDOViewSetImpl)view.getViewSet()).remove(view);
synchronized (views)
{
- if (views.remove(resourceSet) == null)
+ if (!views.remove(view))
{
return;
}
@@ -417,7 +414,7 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD
try
{
- new ViewsChangedRequest(channel, view.getViewID(), CDOProtocolConstants.VIEW_CLOSED).send();
+ getFailOverStrategy().send(new ViewsChangedRequest(channel, view.getViewID(), CDOProtocolConstants.VIEW_CLOSED));
}
catch (Exception ex)
{
@@ -479,7 +476,7 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD
public CDOIDMetaRange registerEPackage(EPackage ePackage)
{
CDOIDMetaRange range = registerEPackage(ePackage, lastTempMetaID + 1, idToMetaInstanceMap, metaInstanceToIDMap);
- lastTempMetaID = ((CDOIDTemp)range.getUpperBound()).getIntValue();
+ lastTempMetaID = ((CDOIDTempMeta)range.getUpperBound()).getIntValue();
return range;
}
@@ -573,11 +570,11 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD
* @since 2.0
*/
public void handleCommitNotification(long timeStamp, Set<CDOIDAndVersion> dirtyOIDs,
- Collection<CDORevisionDelta> deltas, CDOViewImpl excludedView)
+ Collection<CDOID> detachedObjects, Collection<CDORevisionDelta> deltas, CDOViewImpl excludedView)
{
if (isPassiveUpdateEnabled())
{
- notifyInvalidation(timeStamp, dirtyOIDs, excludedView);
+ notifyInvalidation(timeStamp, dirtyOIDs, detachedObjects, excludedView);
}
handleChangeSubcription(deltas, excludedView);
@@ -586,12 +583,14 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD
/**
* @since 2.0
*/
+ @SuppressWarnings("unchecked")
public void handleSync(Set<CDOIDAndVersion> dirtyOIDs)
{
- notifyInvalidation(CDORevision.UNSPECIFIED_DATE, dirtyOIDs, null);
+ notifyInvalidation(CDORevision.UNSPECIFIED_DATE, dirtyOIDs, Collections.EMPTY_LIST, null);
}
- private void notifyInvalidation(long timeStamp, Set<CDOIDAndVersion> dirtyOIDs, CDOViewImpl excludedView)
+ private void notifyInvalidation(long timeStamp, Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects,
+ CDOViewImpl excludedView)
{
for (CDOIDAndVersion dirtyOID : dirtyOIDs)
{
@@ -603,14 +602,25 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD
}
}
+ for (CDOID id : detachedObjects)
+ {
+ InternalCDORevision revision = getRevisionManager().getRevision(id, 0, false);
+ if (revision != null)
+ {
+ revision.setRevised(timeStamp - 1);
+ }
+ }
+
dirtyOIDs = Collections.unmodifiableSet(dirtyOIDs);
+ detachedObjects = Collections.unmodifiableCollection(detachedObjects);
+
for (CDOViewImpl view : getViews())
{
if (view != excludedView)
{
try
{
- view.handleInvalidation(timeStamp, dirtyOIDs);
+ view.handleInvalidation(timeStamp, dirtyOIDs, detachedObjects);
}
catch (RuntimeException ex)
{
@@ -697,33 +707,16 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD
protected void attach(ResourceSet resourceSet, CDOViewImpl view)
{
- if (CDOUtil.getView(resourceSet) != null)
- {
- throw new IllegalStateException("CDO view already open");
- }
-
- resourceSet.setPackageRegistry(new EPackageRegistryImpl(packageRegistry));
- CDOUtil.prepareResourceSet(resourceSet);
-
- Map<URI, Resource> resourceMap = null;
- if (resourceSet instanceof ResourceSetImpl)
- {
- ResourceSetImpl rs = (ResourceSetImpl)resourceSet;
- resourceMap = rs.getURIResourceMap();
- rs.setURIResourceMap(new ProxyResolverURIResourceMap(view, resourceMap));
- }
- else
- {
- throw new ImplementationError("Not a " + ResourceSetImpl.class.getName() + ": "
- + resourceSet.getClass().getName());
- }
-
+ CDOViewSet viewSet = CDOUtil.prepareResourceSet(resourceSet);
synchronized (views)
{
- views.put(resourceSet, view);
+ views.add(view);
}
- resourceSet.eAdapters().add(view);
+ // Link ViewSet with View
+ view.setViewSet(viewSet);
+ ((CDOViewSetImpl)viewSet).add(view);
+
sendViewsNotification(view);
fireElementAddedEvent(view);
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSingleTransactionStrategy.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSingleTransactionStrategy.java
new file mode 100644
index 0000000000..b398b46258
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSingleTransactionStrategy.java
@@ -0,0 +1,92 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo;
+
+import org.eclipse.emf.cdo.CDOSavepoint;
+import org.eclipse.emf.cdo.CDOSession;
+
+import org.eclipse.emf.internal.cdo.bundle.OM;
+import org.eclipse.emf.internal.cdo.protocol.CommitTransactionRequest;
+import org.eclipse.emf.internal.cdo.protocol.CommitTransactionResult;
+
+import org.eclipse.net4j.channel.IChannel;
+import org.eclipse.net4j.signal.failover.IFailOverStrategy;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+import org.eclipse.net4j.util.transaction.TransactionException;
+
+/**
+ * @author Simon McDuff
+ * @since 2.0
+ */
+public class CDOSingleTransactionStrategy implements CDOTransactionStrategy
+{
+ public static final CDOSingleTransactionStrategy INSTANCE = new CDOSingleTransactionStrategy();
+
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_TRANSCTION, CDOSingleTransactionStrategy.class);
+
+ public CDOSingleTransactionStrategy()
+ {
+ }
+
+ public void commit(InternalCDOTransaction transaction) throws Exception
+ {
+ CDOCommitContext commitContext = transaction.createCommitContext();
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("CDOCommitContext.preCommit");
+ }
+
+ commitContext.preCommit();
+
+ CDOSession session = transaction.getSession();
+ IChannel channel = session.getChannel();
+ IFailOverStrategy failOverStrategy = session.getFailOverStrategy();
+ CommitTransactionRequest request = new CommitTransactionRequest(channel, commitContext);
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Sending commit request");
+ }
+
+ CommitTransactionResult result = failOverStrategy.send(request, transaction.getCommitTimeout());
+ String rollbackMessage = result.getRollbackMessage();
+ if (rollbackMessage != null)
+ {
+ throw new TransactionException(rollbackMessage);
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("CDOCommitContext.postCommit");
+ }
+
+ commitContext.postCommit(result);
+ }
+
+ public void rollback(InternalCDOTransaction transaction, CDOSavepoint savepoint, boolean remote)
+ {
+ transaction.handleRollback(savepoint, remote);
+ }
+
+ public CDOSavepoint setSavepoint(InternalCDOTransaction transaction)
+ {
+ return transaction.handleSetSavepoint();
+ }
+
+ public void setTarget(InternalCDOTransaction transaction)
+ {
+ // Do nothing
+ }
+
+ public void unsetTarget(InternalCDOTransaction transaction)
+ {
+ // Do nothing
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java
index c0cbd0aa73..c9f4d856aa 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java
@@ -9,6 +9,9 @@
* Eike Stepper - initial API and implementation
* Simon McDuff - http://bugs.eclipse.org/201266
* Simon McDuff - http://bugs.eclipse.org/215688
+ * Simon McDuff - http://bugs.eclipse.org/213402
+ * Eike Stepper & Simon McDuff - http://bugs.eclipse.org/204890
+ * Simon McDuff - http://bugs.eclipse.org/246705
**************************************************************************/
package org.eclipse.emf.internal.cdo;
@@ -24,27 +27,27 @@ import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
import org.eclipse.emf.cdo.common.util.TransportException;
-import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
-import org.eclipse.emf.cdo.util.CDOUtil;
-import org.eclipse.emf.cdo.util.ServerException;
import org.eclipse.emf.internal.cdo.bundle.OM;
import org.eclipse.emf.internal.cdo.protocol.CommitTransactionResult;
-import org.eclipse.emf.internal.cdo.protocol.ResourceIDRequest;
import org.eclipse.emf.internal.cdo.protocol.VerifyRevisionRequest;
import org.eclipse.emf.internal.cdo.util.FSMUtil;
import org.eclipse.net4j.channel.IChannel;
import org.eclipse.net4j.signal.failover.IFailOverStrategy;
+import org.eclipse.net4j.util.collection.Pair;
import org.eclipse.net4j.util.fsm.FiniteStateMachine;
import org.eclipse.net4j.util.fsm.ITransition;
import org.eclipse.net4j.util.om.trace.ContextTracer;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.EStoreEObjectImpl;
+import org.eclipse.emf.ecore.resource.Resource;
-import java.text.MessageFormat;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -121,8 +124,8 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
init(CDOState.DIRTY, CDOEvent.COMMIT, new CommitTransition());
init(CDOState.DIRTY, CDOEvent.ROLLBACK, new RollbackTransition());
- init(CDOState.PROXY, CDOEvent.PREPARE, new LoadResourceTransition());// Resources start in PROXY instead TRANSIENT
- init(CDOState.PROXY, CDOEvent.ATTACH, IGNORE);// Resources must not FAIL
+ init(CDOState.PROXY, CDOEvent.PREPARE, FAIL);
+ init(CDOState.PROXY, CDOEvent.ATTACH, FAIL);
init(CDOState.PROXY, CDOEvent.DETACH, new DetachTransition());
init(CDOState.PROXY, CDOEvent.READ, new LoadTransition(false));
init(CDOState.PROXY, CDOEvent.WRITE, new LoadTransition(true));
@@ -143,27 +146,44 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
+ * object is already attached in EMF world. It contains all the information needed to know where it will be connected.
+ * We used a mapOfContents only for performance reason.
+ *
* @since 2.0
*/
- public void attach(InternalCDOObject object, CDOResource resource, CDOView view)
+ public void attach(InternalCDOObject object, CDOTransactionImpl transaction)
{
- ResourceAndView data = new ResourceAndView(resource, (CDOViewImpl)view);
+ Map<InternalCDOObject, List<InternalCDOObject>> mapOfContents = new HashMap<InternalCDOObject, List<InternalCDOObject>>();
+ attach1(object, new Pair<CDOTransactionImpl, Map<InternalCDOObject, List<InternalCDOObject>>>(transaction,
+ mapOfContents));
+ attach2(object, mapOfContents);
+ }
- // Phase 1: TRANSIENT --> PREPARED
+ /**
+ * Phase 1: TRANSIENT --> PREPARED
+ */
+ private void attach1(InternalCDOObject object,
+ Pair<CDOTransactionImpl, Map<InternalCDOObject, List<InternalCDOObject>>> transactionAndMapOfContents)
+ {
if (TRACER.isEnabled())
{
- TRACER.format("PREPARE: {0} --> {1}", object, view);
+ TRACER.format("PREPARE: {0} --> {1}", object, transactionAndMapOfContents.getElement1());
}
- process(object, CDOEvent.PREPARE, data);
+ process(object, CDOEvent.PREPARE, transactionAndMapOfContents);
+ }
- // Phase 2: PREPARED --> NEW
+ /**
+ * Phase 2: PREPARED --> NEW
+ */
+ private void attach2(InternalCDOObject object, Map<InternalCDOObject, List<InternalCDOObject>> mapOfContents)
+ {
if (TRACER.isEnabled())
{
- TRACER.format("ATTACH: {0} --> {1}", object, view);
+ TRACER.format("ATTACH: {0} --> {1}", object, mapOfContents);
}
- process(object, CDOEvent.ATTACH, null);
+ process(object, CDOEvent.ATTACH, mapOfContents);
}
public void detach(InternalCDOObject object)
@@ -263,12 +283,20 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
public void invalidate(InternalCDOObject object, long timeStamp)
{
+ invalidate(object, false, timeStamp);
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void invalidate(InternalCDOObject object, boolean detach, long timeStamp)
+ {
if (TRACER.isEnabled())
{
trace(object, CDOEvent.INVALIDATE);
}
- process(object, CDOEvent.INVALIDATE, timeStamp);
+ process(object, CDOEvent.INVALIDATE, new Pair<Boolean, Long>(detach, timeStamp));
}
public void commit(InternalCDOObject object, CommitTransactionResult result)
@@ -331,28 +359,6 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
/**
- * @author Eike Stepper
- */
- private static final class ResourceAndView
- {
- public CDOResource resource;
-
- public CDOViewImpl view;
-
- public ResourceAndView(CDOResource resource, CDOViewImpl view)
- {
- this.resource = resource;
- this.view = view;
- }
-
- @Override
- public String toString()
- {
- return MessageFormat.format("ResourceAndView({0}, {1})", resource, view);
- }
- }
-
- /**
* Prepares a tree of transient objects to be subsequently {@link AttachTransition attached} to a CDOView.
* <p>
* Execution is recursive and includes:
@@ -367,37 +373,49 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
* @see AttachTransition
* @author Eike Stepper
*/
- private final class PrepareTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, ResourceAndView>
+ @SuppressWarnings("unchecked")
+ private final class PrepareTransition
+ implements
+ ITransition<CDOState, CDOEvent, InternalCDOObject, Pair<CDOTransactionImpl, Map<InternalCDOObject, List<InternalCDOObject>>>>
{
- public void execute(InternalCDOObject object, CDOState state, CDOEvent event, ResourceAndView data)
+ public void execute(InternalCDOObject object, CDOState state, CDOEvent event,
+ Pair<CDOTransactionImpl, Map<InternalCDOObject, List<InternalCDOObject>>> transactionAndMapOfContents)
{
- CDOTransactionImpl transaction = data.view.toTransaction();
+ CDOTransactionImpl transaction = transactionAndMapOfContents.getElement1();
+ Map<InternalCDOObject, List<InternalCDOObject>> mapOfContents = transactionAndMapOfContents.getElement2();
+
CDORevisionManager revisionManager = transaction.getSession().getRevisionManager();
// Prepare object
CDOID id = transaction.getNextTemporaryID();
object.cdoInternalSetID(id);
- object.cdoInternalSetResource(data.resource);
- object.cdoInternalSetView(data.view);
+ object.cdoInternalSetView(transaction);
changeState(object, CDOState.PREPARED);
// Create new revision
CDOClass cdoClass = object.cdoClass();
InternalCDORevision revision = (InternalCDORevision)CDORevisionUtil.create(revisionManager, cdoClass, id);
revision.setVersion(-1);
- revision.setResourceID(data.resource.cdoID());
+
object.cdoInternalSetRevision(revision);
// Register object
- data.view.registerObject(object);
+ transaction.registerObject(object);
transaction.registerNew(object);
+ // Build a list to access the same object in AttachTransition.
+ // This is an optimization. Accessing object from eStore/getObject takes more time than directly.
+ List<InternalCDOObject> contents = new ArrayList<InternalCDOObject>();
+
// Prepare content tree
- for (Iterator<InternalCDOObject> it = FSMUtil.iterator(object.eContents(), transaction); it.hasNext();)
+ for (Iterator<InternalCDOObject> it = FSMUtil.getProperContents(object); it.hasNext();)
{
InternalCDOObject content = it.next();
- INSTANCE.process(content, CDOEvent.PREPARE, data);
+ contents.add(content);
+ INSTANCE.process(content, CDOEvent.PREPARE,
+ new Pair<CDOTransactionImpl, Map<InternalCDOObject, List<InternalCDOObject>>>(transaction, mapOfContents));
}
+ mapOfContents.put(object, contents.size() == 0 ? Collections.EMPTY_LIST : contents);
}
}
@@ -419,19 +437,21 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
* @see PrepareTransition
* @author Eike Stepper
*/
- private final class AttachTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Object>
+ private final class AttachTransition implements
+ ITransition<CDOState, CDOEvent, InternalCDOObject, Map<InternalCDOObject, List<InternalCDOObject>>>
{
- public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Object NULL)
+ public void execute(InternalCDOObject object, CDOState state, CDOEvent event,
+ Map<InternalCDOObject, List<InternalCDOObject>> mapOfContents)
{
- CDOTransactionImpl transaction = (CDOTransactionImpl)object.cdoView();
object.cdoInternalPostAttach();
changeState(object, CDOState.NEW);
- // Attach content tree
- for (Iterator<?> it = FSMUtil.iterator(object.eContents(), transaction); it.hasNext();)
+ List<InternalCDOObject> contents = mapOfContents.get(object);
+
+ // Prepare content tree
+ for (InternalCDOObject content : contents)
{
- InternalCDOObject content = (InternalCDOObject)it.next();
- INSTANCE.process(content, CDOEvent.ATTACH, null);
+ INSTANCE.process(content, CDOEvent.ATTACH, mapOfContents);
}
}
}
@@ -444,13 +464,26 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Object NULL)
{
CDOTransactionImpl transaction = (CDOTransactionImpl)object.cdoView();
+
+ transaction.detachObject(object);
+
+ object.cdoInternalPostDetach();
object.cdoInternalSetState(CDOState.TRANSIENT);
- // Detach content tree
- for (Iterator<?> it = FSMUtil.iterator(object.eContents(), transaction); it.hasNext();)
+ boolean isResource = object instanceof Resource;
+ // Prepare content tree
+ for (Iterator<EObject> it = object.eContents().iterator(); it.hasNext();)
{
- InternalCDOObject content = (InternalCDOObject)it.next();
- INSTANCE.process(content, CDOEvent.DETACH, null);
+ InternalEObject eObject = (InternalEObject)it.next();
+ boolean isDirectlyConnected = isResource && eObject.eDirectResource() == object;
+ if (isDirectlyConnected || eObject.eDirectResource() == null)
+ {
+ InternalCDOObject content = FSMUtil.adapt(eObject, transaction);
+ if (content != null)
+ {
+ INSTANCE.process(content, CDOEvent.DETACH, object);
+ }
+ }
}
}
}
@@ -571,12 +604,20 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
/**
* @author Eike Stepper
*/
- private class InvalidateTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Long>
+ private class InvalidateTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Pair<Boolean, Long>>
{
- public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Long timeStamp)
+ public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Pair<Boolean, Long> detachAndTimeStamp)
{
- reviseObject(object, timeStamp);
- changeState(object, CDOState.PROXY);
+ if (detachAndTimeStamp.getElement1())
+ {
+ object.cdoInternalPostDetach();
+ object.cdoInternalSetState(CDOState.TRANSIENT);
+ }
+ else
+ {
+ reviseObject(object, detachAndTimeStamp.getElement2());
+ changeState(object, CDOState.PROXY);
+ }
}
protected void reviseObject(InternalCDOObject object, Long timeStamp)
@@ -592,9 +633,9 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
private final class ConflictTransition extends InvalidateTransition
{
@Override
- public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Long timeStamp)
+ public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Pair<Boolean, Long> detachAndTimeStamp)
{
- reviseObject(object, timeStamp);
+ reviseObject(object, detachAndTimeStamp.getElement2());
CDOViewImpl view = (CDOViewImpl)object.cdoView();
CDOTransactionImpl transaction = view.toTransaction();
transaction.setConflict(object);
@@ -629,51 +670,6 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
}
}
}
-
- /**
- * @author Eike Stepper
- */
- private final class LoadResourceTransition implements
- ITransition<CDOState, CDOEvent, InternalCDOObject, ResourceAndView>
- {
- public void execute(InternalCDOObject object, CDOState state, CDOEvent event, ResourceAndView data)
- {
- CDOID id = requestID(data.resource, data.view);
- if (id.isNull())
- {
- throw new ServerException("Resource not available: " + data.resource.getPath());
- }
-
- // Prepare object
- object.cdoInternalSetID(id);
- object.cdoInternalSetResource(data.resource);
- object.cdoInternalSetView(data.view);
-
- // Register object
- data.view.registerObject(object);
- }
-
- private CDOID requestID(CDOResource resource, CDOViewImpl view)
- {
- try
- {
- String path = CDOUtil.extractResourcePath(resource.getURI());
- CDOSession session = view.getSession();
-
- IFailOverStrategy failOverStrategy = session.getFailOverStrategy();
- ResourceIDRequest request = new ResourceIDRequest(session.getChannel(), path);
- return failOverStrategy.send(request);
- }
- catch (RuntimeException ex)
- {
- throw ex;
- }
- catch (Exception ex)
- {
- throw new TransportException(ex);
- }
- }
- }
}
/**
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStore.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStore.java
index 1ab1c7f29e..89db55dacd 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStore.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStore.java
@@ -8,6 +8,9 @@
* Contributors:
* Eike Stepper - initial API and implementation
* Simon McDuff - http://bugs.eclipse.org/201266
+ * Eike Stepper & Simon McDuff - http://bugs.eclipse.org/204890
+ * Simon McDuff - http://bugs.eclipse.org/246705
+ * Simon McDuff - http://bugs.eclipse.org/246622
**************************************************************************/
package org.eclipse.emf.internal.cdo;
@@ -47,6 +50,12 @@ import java.util.HashSet;
import java.util.Set;
/**
+ * CDORevision needs to follow these rules:<br>
+ * - Keep CDOID only when the object (!isNew && !isTransient) // Only when CDOID will not changed.<br>
+ * - Keep EObject for external reference, new, transient and that until commit time.<br>
+ * It is important since these objects could changed and we need to keep a reference to {@link EObject} until the end.
+ * It is the reason why {@link CDOStore} always call {@link CDOViewImpl#convertObjectToID(Object, boolean)} with true.
+ *
* @author Eike Stepper
*/
public final class CDOStore implements EStore
@@ -55,6 +64,13 @@ public final class CDOStore implements EStore
private CDOViewImpl view;
+ // Used for optimization. Often multiple call to CDStore will be sent like size and than add.
+ private EStructuralFeature lastLookupEFeature;
+
+ private CDOFeature lastLookupCDOFeature;
+
+ private Object lock = new Object();
+
public CDOStore(CDOViewImpl view)
{
this.view = view;
@@ -68,23 +84,22 @@ public final class CDOStore implements EStore
/**
* @since 2.0
*/
- public void setContainer(InternalEObject eObject, CDOResource newResource, InternalEObject newContainer,
+ public void setContainer(InternalEObject eObject, CDOResource newResource, InternalEObject newEContainer,
int newContainerFeatureID)
{
InternalCDOObject cdoObject = getCDOObject(eObject);
if (TRACER.isEnabled())
{
- TRACER.format("setContainer({0}, {1}, {2}, {3})", cdoObject, newResource, newContainer, newContainerFeatureID);
+ TRACER.format("setContainer({0}, {1}, {2}, {3})", cdoObject, newResource, newEContainer, newContainerFeatureID);
}
+ Object newContainerID = newEContainer == null ? CDOID.NULL : ((CDOViewImpl)cdoObject.cdoView()).convertObjectToID(
+ newEContainer, true);
+ CDOID newResourceID = newResource == null ? CDOID.NULL : newResource.cdoID();
- CDOViewImpl newView = (CDOViewImpl)cdoObject.cdoView();
- CDOID containerID = (CDOID)newView.convertObjectToID(newContainer);
- CDOID resourceID = newResource == null ? null : newResource.cdoID();
-
- CDOFeatureDelta delta = new CDOContainerFeatureDeltaImpl(containerID, newContainerFeatureID);
+ CDOFeatureDelta delta = new CDOContainerFeatureDeltaImpl(newResourceID, newContainerID, newContainerFeatureID);
InternalCDORevision revision = getRevisionForWriting(cdoObject, delta);
- revision.setResourceID(resourceID);
- revision.setContainerID(containerID);
+ revision.setResourceID(newResourceID);
+ revision.setContainerID(newContainerID);
revision.setContainingFeatureID(newContainerFeatureID);
}
@@ -97,8 +112,8 @@ public final class CDOStore implements EStore
}
InternalCDORevision revision = getRevisionForReading(cdoObject);
- CDOID id = revision.getContainerID();
- return (InternalEObject)((CDOViewImpl)cdoObject.cdoView()).convertIDToObject(id);
+
+ return (InternalEObject)((CDOViewImpl)cdoObject.cdoView()).convertIDToObject(revision.getContainerID());
}
public int getContainingFeatureID(InternalEObject eObject)
@@ -130,9 +145,14 @@ public final class CDOStore implements EStore
view.getFeatureAnalyzer().preTraverseFeature(cdoObject, cdoFeature, index);
InternalCDORevision revision = getRevisionForReading(cdoObject);
- Object value = get(revision, cdoFeature, index);
+ Object value = revision.get(cdoFeature, index);
if (cdoFeature.isReference())
{
+ if (value instanceof CDOReferenceProxy)
+ {
+ value = ((CDOReferenceProxy)value).resolve();
+ }
+
if (cdoFeature.isMany() && value instanceof CDOID)
{
CDOID id = (CDOID)value;
@@ -200,7 +220,7 @@ public final class CDOStore implements EStore
if (cdoFeature.isReference())
{
- value = ((CDOViewImpl)cdoObject.cdoView()).convertObjectToID(value);
+ value = ((CDOViewImpl)cdoObject.cdoView()).convertObjectToID(value, true);
}
InternalCDORevision revision = getRevisionForReading(cdoObject);
@@ -218,7 +238,7 @@ public final class CDOStore implements EStore
if (cdoFeature.isReference())
{
- value = ((CDOViewImpl)cdoObject.cdoView()).convertObjectToID(value);
+ value = ((CDOViewImpl)cdoObject.cdoView()).convertObjectToID(value, true);
}
InternalCDORevision revision = getRevisionForReading(cdoObject);
@@ -236,7 +256,7 @@ public final class CDOStore implements EStore
if (cdoFeature.isReference())
{
- value = ((CDOViewImpl)cdoObject.cdoView()).convertObjectToID(value);
+ value = ((CDOViewImpl)cdoObject.cdoView()).convertObjectToID(value, true);
}
InternalCDORevision revision = getRevisionForReading(cdoObject);
@@ -330,22 +350,13 @@ public final class CDOStore implements EStore
{
((CDOReferenceProxy)oldValue).resolve();
}
-
- if (cdoFeature.isContainment() && value != null)
- {
- handleContainmentAdd(cdoObject, value);
- }
+ value = ((CDOViewImpl)cdoObject.cdoView()).convertObjectToID(value, true);
}
Object oldValue = revision.set(cdoFeature, index, value);
-
if (cdoFeature.isReference())
{
oldValue = ((CDOViewImpl)cdoObject.cdoView()).convertIDToObject(oldValue);
- if (cdoFeature.isContainment() && oldValue != null)
- {
- handleContainmentRemove(cdoObject, value);
- }
}
return oldValue;
@@ -377,12 +388,7 @@ public final class CDOStore implements EStore
if (cdoFeature.isReference())
{
- if (cdoFeature.isContainment() && value != null)
- {
- handleContainmentAdd(cdoObject, value);
- }
-
- value = ((CDOViewImpl)cdoObject.cdoView()).convertObjectToID(value);
+ value = ((CDOViewImpl)cdoObject.cdoView()).convertObjectToID(value, true);
}
CDOFeatureDelta delta = new CDOAddFeatureDeltaImpl(cdoFeature, index, value);
@@ -410,10 +416,6 @@ public final class CDOStore implements EStore
}
result = ((CDOViewImpl)cdoObject.cdoView()).convertIDToObject(result);
- if (cdoFeature.isContainment() && result != null)
- {
- handleContainmentRemove(cdoObject, result);
- }
}
return result;
@@ -477,6 +479,14 @@ public final class CDOStore implements EStore
private CDOFeature getCDOFeature(InternalCDOObject cdoObject, EStructuralFeature eFeature)
{
+ synchronized (lock)
+ {
+ if (eFeature == lastLookupEFeature)
+ {
+ return lastLookupCDOFeature;
+ }
+ }
+
CDOViewImpl view = (CDOViewImpl)cdoObject.cdoView();
if (view == null)
{
@@ -484,31 +494,15 @@ public final class CDOStore implements EStore
}
CDOSessionPackageManagerImpl packageManager = view.getSession().getPackageManager();
- return ModelUtil.getCDOFeature(eFeature, packageManager);
- }
-
- private void handleContainmentAdd(InternalCDOObject container, Object value)
- {
- CDOViewImpl containerView = (CDOViewImpl)container.cdoView();
- InternalCDOObject contained = getCDOObject(value);
- FSMUtil.checkLegacySystemAvailability(containerView.getSession(), contained);
+ CDOFeature cdoFeature = ModelUtil.getCDOFeature(eFeature, packageManager);
- CDOViewImpl containedView = (CDOViewImpl)contained.cdoView();
- if (containedView != containerView)
+ synchronized (lock)
{
- if (containedView != null)
- {
- CDOStateMachine.INSTANCE.detach(contained);
- }
-
- CDOStateMachine.INSTANCE.attach(contained, container.cdoResource(), containerView);
+ lastLookupEFeature = eFeature;
+ lastLookupCDOFeature = cdoFeature;
}
- }
+ return cdoFeature;
- private void handleContainmentRemove(InternalCDOObject container, Object value)
- {
- // InternalCDOObject contained = getCDOObject(value);
- // CDOStateMachine.INSTANCE.detach(contained);
}
private void loadAhead(InternalCDORevision revision, CDOFeature cdoFeature, CDOID id, int index)
@@ -551,19 +545,6 @@ public final class CDOStore implements EStore
}
}
- private Object get(InternalCDORevision revision, CDOFeature cdoFeature, int index)
- {
- Object result = revision.get(cdoFeature, index);
- if (cdoFeature.isReference())
- {
- if (result instanceof CDOReferenceProxy)
- {
- result = ((CDOReferenceProxy)result).resolve();
- }
- }
- return result;
- }
-
private static InternalCDORevision getRevisionForReading(InternalCDOObject cdoObject)
{
CDOStateMachine.INSTANCE.read(cdoObject);
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java
index 6e415b1e0c..21ae8ae426 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java
@@ -11,17 +11,19 @@
* Simon McDuff - http://bugs.eclipse.org/233314
* Simon McDuff - http://bugs.eclipse.org/215688
* Simon McDuff - http://bugs.eclipse.org/233490
+ * Simon McDuff - http://bugs.eclipse.org/213402
+ * Simon McDuff - http://bugs.eclipse.org/246620
**************************************************************************/
package org.eclipse.emf.internal.cdo;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOSavepoint;
import org.eclipse.emf.cdo.CDOState;
-import org.eclipse.emf.cdo.CDOTransaction;
import org.eclipse.emf.cdo.CDOTransactionConflictEvent;
import org.eclipse.emf.cdo.CDOTransactionFinishedEvent;
import org.eclipse.emf.cdo.CDOTransactionHandler;
import org.eclipse.emf.cdo.CDOTransactionStartedEvent;
+import org.eclipse.emf.cdo.CDOViewResourcesEvent;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDAndVersion;
import org.eclipse.emf.cdo.common.id.CDOIDTemp;
@@ -30,27 +32,22 @@ import org.eclipse.emf.cdo.common.model.CDOPackage;
import org.eclipse.emf.cdo.common.revision.CDORevision;
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.CDOListFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDeltaUtil;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl;
-import org.eclipse.emf.cdo.internal.common.revision.delta.CDORevisionDeltaImpl;
import org.eclipse.emf.cdo.spi.common.InternalCDOPackage;
+import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.InternalCDORevisionDelta;
-import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.cdo.util.CDOURIUtil;
import org.eclipse.emf.internal.cdo.bundle.OM;
-import org.eclipse.emf.internal.cdo.protocol.CommitTransactionRequest;
import org.eclipse.emf.internal.cdo.protocol.CommitTransactionResult;
import org.eclipse.emf.internal.cdo.util.CompletePackageClosure;
import org.eclipse.emf.internal.cdo.util.IPackageClosure;
import org.eclipse.emf.internal.cdo.util.ModelUtil;
-import org.eclipse.net4j.channel.IChannel;
-import org.eclipse.net4j.signal.failover.IFailOverStrategy;
import org.eclipse.net4j.util.ImplementationError;
-import org.eclipse.net4j.util.collection.MultiMap;
import org.eclipse.net4j.util.event.Notifier;
import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.net4j.util.transaction.TransactionException;
@@ -69,12 +66,11 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentHashMap;
/**
* @author Eike Stepper
*/
-public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
+public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransaction
{
private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_TRANSCTION, CDOTransactionImpl.class);
@@ -83,8 +79,6 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
*/
private List<CDOTransactionHandler> handlers = new ArrayList<CDOTransactionHandler>(0);
- private List<CDOPackage> newPackages;
-
private CDOSavepointImpl lastSavepoint = new CDOSavepointImpl(this, null);
private CDOSavepointImpl firstSavepoint = lastSavepoint;
@@ -97,6 +91,8 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
private int lastTemporaryID;
+ private CDOTransactionStrategy transactionStrategy;
+
public CDOTransactionImpl(int id, CDOSessionImpl session)
{
super(session, id);
@@ -162,11 +158,6 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
commitTimeout = timeout;
}
- public List<CDOPackage> getNewPackages()
- {
- return Collections.unmodifiableList(newPackages);
- }
-
public CDOIDTemp getNextTemporaryID()
{
return CDOIDUtil.createTempObject(++lastTemporaryID);
@@ -174,7 +165,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
public CDOResource createResource(String path)
{
- URI createURI = CDOUtil.createResourceURI(path);
+ URI createURI = CDOURIUtil.createResourceURI(this, path);
return (CDOResource)getResourceSet().createResource(createURI);
}
@@ -185,99 +176,121 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
{
return createResource(path);
}
- else
- {
- return addResource(id, path);
- }
+
+ return (CDOResource)getObject(id);
}
/**
* @since 2.0
*/
- public CDOSavepointImpl getLastSavepoint()
- {
- return lastSavepoint;
- }
- public void commit() throws TransactionException
+ public void attach(CDOResourceImpl cdoResource)
{
- if (dirty)
+ try
+ {
+ CDOStateMachine.INSTANCE.attach(cdoResource, this);
+ fireEvent(new ResourcesEvent(cdoResource.getPath(), ResourcesEvent.Kind.ADDED));
+ }
+ catch (RuntimeException ex)
{
- if (TRACER.isEnabled())
+ OM.LOG.error(ex);
+
+ try
{
- TRACER.trace("commit()");
+ ((InternalCDOObject)cdoResource).cdoInternalSetState(CDOState.NEW);
+ getResourceSet().getResources().remove(cdoResource);
}
-
- for (CDOTransactionHandler handler : getHandlers())
+ catch (RuntimeException ignore)
{
- handler.committingTransaction(this);
}
- try
- {
- newPackages = analyzeNewPackages();
- Collection<CDORevisionDelta> deltas = getRevisionDeltas().values();
+ throw ex;
+ }
+ }
- for (CDOSavepointImpl savepoint = lastSavepoint; savepoint != null; savepoint = savepoint
- .getPreviousSavepoint())
- {
- preCommit(savepoint.getNewObjects());
- preCommit(savepoint.getDirtyObjects());
- }
+ /**
+ * @since 2.0
+ */
- CDOSessionImpl session = getSession();
- IChannel channel = session.getChannel();
- IFailOverStrategy failOverStrategy = session.getFailOverStrategy();
- CommitTransactionRequest request = new CommitTransactionRequest(channel, this);
+ public void detach(CDOResourceImpl cdoResource)
+ {
+ CDOStateMachine.INSTANCE.detach(cdoResource);
+ fireEvent(new ResourcesEvent(cdoResource.getPath(), ResourcesEvent.Kind.REMOVED));
+ }
- CommitTransactionResult result = failOverStrategy.send(request, commitTimeout);
- String rollbackMessage = result.getRollbackMessage();
- if (rollbackMessage != null)
- {
- throw new TransactionException(rollbackMessage);
- }
+ /**
+ * @since 2.0
+ */
+ public CDOSavepointImpl getLastSavepoint()
+ {
+ return lastSavepoint;
+ }
- for (CDOSavepointImpl savepoint = lastSavepoint; savepoint != null; savepoint = savepoint
- .getPreviousSavepoint())
- {
- postCommit(savepoint.getNewResources(), result);
- postCommit(savepoint.getNewObjects(), result);
- postCommit(savepoint.getDirtyObjects(), result);
- }
+ /**
+ * @since 2.0
+ */
+ public CDOTransactionStrategy getTransactionStrategy()
+ {
+ if (transactionStrategy == null)
+ {
+ transactionStrategy = CDOTransactionStrategy.DEFAULT;
+ transactionStrategy.setTarget(this);
+ }
- for (CDOPackage newPackage : newPackages)
- {
- ((InternalCDOPackage)newPackage).setPersistent(true);
- }
+ return transactionStrategy;
+ }
- getChangeSubscriptionManager().notifyDirtyObjects();
+ /**
+ * @since 2.0
+ */
+ public void setTransactionStrategy(CDOTransactionStrategy transactionStrategy)
+ {
+ if (this.transactionStrategy != null)
+ {
+ this.transactionStrategy.unsetTarget(this);
+ }
- Map<CDOID, CDOObject> dirtyObjects = getDirtyObjects();
- if (!dirtyObjects.isEmpty())
- {
- Set<CDOIDAndVersion> dirtyIDs = new HashSet<CDOIDAndVersion>();
- for (CDOObject dirtyObject : dirtyObjects.values())
- {
- CDORevision revision = dirtyObject.cdoRevision();
- CDOIDAndVersion dirtyID = CDOIDUtil.createIDAndVersion(revision.getID(), revision.getVersion() - 1);
- dirtyIDs.add(dirtyID);
- }
+ this.transactionStrategy = transactionStrategy;
- session.handleCommitNotification(result.getTimeStamp(), dirtyIDs, deltas, this);
- }
+ if (this.transactionStrategy != null)
+ {
+ this.transactionStrategy.setTarget(this);
+ }
+ }
- cleanUp();
- Map<CDOIDTemp, CDOID> idMappings = result.getIDMappings();
- fireEvent(new FinishedEvent(CDOTransactionFinishedEvent.Type.COMMITTED, idMappings));
- }
- catch (RuntimeException ex)
- {
- throw ex;
- }
- catch (Exception ex)
- {
- throw new TransactionException(ex);
- }
+ @Override
+ public InternalCDOObject getObject(CDOID id, boolean loadOnDemand)
+ {
+ if (lastSavepoint.getSharedDetachedObjects().contains(id))
+ {
+ throw new IllegalArgumentException("Cannot access object with id " + id
+ + " anymore. It was removed from this view.");
+ }
+
+ return super.getObject(id, loadOnDemand);
+ }
+
+ /**
+ * @since 2.0
+ */
+ public CDOCommitContext createCommitContext()
+ {
+ return new CDOCommitContextImpl();
+ }
+
+ public void commit() throws TransactionException
+ {
+ try
+ {
+ getTransactionStrategy().commit(this);
+ }
+ catch (TransactionException ex)
+ {
+ throw ex;
+ }
+ catch (Exception ex)
+ {
+ throw new TransactionException(ex);
}
}
@@ -360,9 +373,10 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
Map<CDOID, CDOObject> dirtyObjects = itrSavepoint.getDirtyObjects();
if (!dirtyObjects.isEmpty())
{
- for (CDOObject dirtyObject : dirtyObjects.values())
+ for (Entry<CDOID, CDOObject> entryDirty : dirtyObjects.entrySet())
{
- CDOStateMachine.INSTANCE.rollback((InternalCDOObject)dirtyObject, remote);
+ InternalCDOObject internalDirtyObject = (InternalCDOObject)entryDirty.getValue();
+ cleanObject(internalDirtyObject, getRevision(entryDirty.getKey(), true));
}
}
@@ -377,10 +391,13 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
private void loadSavepoint(CDOSavepoint savepoint, Set<CDOID> idsOfNewObjectWithDeltas)
{
+ lastSavepoint.getSharedDetachedObjects().clear();
+
Map<CDOID, CDOObject> dirtyObjects = getDirtyObjects();
Map<CDOID, CDOObject> newObjMaps = getNewObjects();
Map<CDOID, CDOResource> newResources = getNewResources();
Map<CDOID, CDORevision> newBaseRevision = getBaseNewObjects();
+ Set<CDOID> detachedObjects = getDetachedObjects();
// Reload the objects (NEW) with their base.
for (CDOID id : idsOfNewObjectWithDeltas)
@@ -395,18 +412,37 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
if (revision != null)
{
object.cdoInternalSetRevision(CDORevisionUtil.copy(revision));
+ object.cdoInternalSetState(CDOState.NEW);
// Load the object from revision to EObject
object.cdoInternalPostLoad();
}
}
+ // We need to register back new objects that are not removed anymore there.
+ for (Entry<CDOID, CDOObject> entryNewObject : newObjMaps.entrySet())
+ {
+ if (!isObjectRegistered(entryNewObject.getKey()))
+ {
+ // Go back to the previous state
+ InternalCDOObject object = (InternalCDOObject)entryNewObject.getValue();
+ cleanObject(object, (InternalCDORevision)object.cdoRevision());
+ object.cdoInternalSetState(CDOState.NEW);
+ registerObject(object);
+ }
+ }
+
for (CDOSavepointImpl itrSavepoint = firstSavepoint; itrSavepoint != savepoint; itrSavepoint = itrSavepoint
.getNextSavepoint())
{
CDOObjectMerger merger = new CDOObjectMerger();
for (CDORevisionDelta delta : itrSavepoint.getRevisionDeltas().values())
{
+ if (delta.getID().isTemporary() && !idsOfNewObjectWithDeltas.contains(delta.getID()))
+ {
+ continue;
+ }
+
Map<CDOID, CDOObject> map = delta.getID().isTemporary() ? newObjMaps : dirtyObjects;
InternalCDOObject object = (InternalCDOObject)map.get(delta.getID());
if (object == null)
@@ -422,27 +458,78 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
}
}
+ // Put persistent objects that we removed in a savepoint to transient
+ for (CDOID id : detachedObjects)
+ {
+ if (!id.isTemporary())
+ {
+ InternalCDOObject object = getObject(id, true);
+ object.cdoInternalPostDetach();
+ object.cdoInternalSetState(CDOState.TRANSIENT);
+ }
+
+ // Recalculate HashSet
+ lastSavepoint.getSharedDetachedObjects().add(id);
+ }
+
dirty = ((CDOSavepointImpl)savepoint).isDirty();
}
/**
* @since 2.0
*/
+ public void detachObject(InternalCDOObject object)
+ {
+ if (object.cdoState() == CDOState.NEW)
+ {
+ Map<CDOID, ? extends CDOObject> map = object instanceof CDOResource ? getLastSavepoint().getNewResources()
+ : getLastSavepoint().getNewObjects();
+
+ // Determine when we added object
+ if (map.containsKey(object.cdoID()))
+ {
+ map.remove(object.cdoID());
+ }
+ else
+ {
+ getLastSavepoint().getDetachedObjects().add(object.cdoID());
+ }
+
+ // deregister object
+ deregisterObject(object);
+ }
+ else
+ {
+ getLastSavepoint().getDetachedObjects().add(object.cdoID());
+ }
+ }
+
+ /**
+ * @since 2.0
+ */
public void rollback(CDOSavepoint savepoint, boolean remote)
{
+ getTransactionStrategy().rollback(this, savepoint, remote);
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void handleRollback(CDOSavepoint savepoint, boolean remote)
+ {
if (savepoint == null)
{
throw new IllegalArgumentException("Save point is null");
}
- if (savepoint.getTransaction() != this)
+ if (savepoint.getUserTransaction() != this)
{
throw new IllegalArgumentException("Save point to rollback doesn't belong to this transaction: " + savepoint);
}
if (TRACER.isEnabled())
{
- TRACER.trace("commit()");
+ TRACER.trace("handleRollback()");
}
try
@@ -491,7 +578,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
/**
* @since 2.0
*/
- public CDOSavepoint setSavepoint()
+ public CDOSavepoint handleSetSavepoint()
{
// Take a copy of all new objects for the current save point
addToBase(lastSavepoint.getNewObjects());
@@ -501,6 +588,14 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
return lastSavepoint;
}
+ /**
+ * @since 2.0
+ */
+ public CDOSavepoint setSavepoint()
+ {
+ return getTransactionStrategy().setSavepoint(this);
+ }
+
private void addToBase(Map<CDOID, ? extends CDOObject> objects)
{
for (CDOObject object : objects.values())
@@ -673,36 +768,12 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
return newPackages;
}
- @SuppressWarnings("unchecked")
- private void preCommit(Map objects)
- {
- if (!objects.isEmpty())
- {
- for (Object object : objects.values())
- {
- ((InternalCDOObject)object).cdoInternalPreCommit();
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- private void postCommit(Map objects, CommitTransactionResult result)
- {
- if (!objects.isEmpty())
- {
- for (Object object : objects.values())
- {
- CDOStateMachine.INSTANCE.commit((InternalCDOObject)object, result);
- }
- }
- }
-
private void cleanUp()
{
- newPackages = null;
lastSavepoint = firstSavepoint;
firstSavepoint.clear();
firstSavepoint.setNextSavepoint(null);
+ firstSavepoint.getSharedDetachedObjects().clear();
dirty = false;
conflict = false;
lastTemporaryID = 0;
@@ -710,116 +781,212 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
public Map<CDOID, CDOObject> getDirtyObjects()
{
- if (lastSavepoint.getPreviousSavepoint() == null)
- {
- return lastSavepoint.getDirtyObjects();
- }
+ return lastSavepoint.getAllDirtyObjects();
+ }
- MultiMap.ListBased<CDOID, CDOObject> dirtyObjects = new MultiMap.ListBased<CDOID, CDOObject>();
- for (CDOSavepointImpl savepoint = lastSavepoint; savepoint != null; savepoint = savepoint.getPreviousSavepoint())
- {
- dirtyObjects.getDelegates().add(savepoint.getDirtyObjects());
- }
+ public Map<CDOID, CDOObject> getNewObjects()
+ {
+ return lastSavepoint.getAllNewObjects();
+ }
- return dirtyObjects;
+ public Map<CDOID, CDOResource> getNewResources()
+ {
+ return lastSavepoint.getAllNewResources();
}
- public Map<CDOID, CDOObject> getNewObjects()
+ /**
+ * @since 2.0
+ */
+ public Map<CDOID, CDORevision> getBaseNewObjects()
{
- if (lastSavepoint.getPreviousSavepoint() == null)
- {
- return Collections.unmodifiableMap(lastSavepoint.getNewObjects());
- }
+ return lastSavepoint.getAllBaseNewObjects();
+ }
- MultiMap.ListBased<CDOID, CDOObject> newObjects = new MultiMap.ListBased<CDOID, CDOObject>();
- for (CDOSavepointImpl savepoint = lastSavepoint; savepoint != null; savepoint = savepoint.getPreviousSavepoint())
- {
- newObjects.getDelegates().add(savepoint.getNewObjects());
- }
+ public Map<CDOID, CDORevisionDelta> getRevisionDeltas()
+ {
+ return lastSavepoint.getAllRevisionDeltas();
+ }
- return newObjects;
+ /**
+ * @since 2.0
+ */
+ public Set<CDOID> getDetachedObjects()
+ {
+ return lastSavepoint.getAllDetachedObjects();
}
- public Map<CDOID, CDOResource> getNewResources()
+ /**
+ * @author Simon McDuff
+ */
+ private class CDOCommitContextImpl implements CDOCommitContext
{
- if (lastSavepoint.getPreviousSavepoint() == null)
+ private Map<CDOID, CDOResource> newResources;
+
+ private Map<CDOID, CDOObject> newObjects;
+
+ private Map<CDOID, CDOObject> dirtyObjects;
+
+ private Map<CDOID, CDORevisionDelta> revisionDeltas;
+
+ private Set<CDOID> detachedObjects;
+
+ private List<CDOPackage> newPackages;
+
+ public CDOCommitContextImpl()
{
- return Collections.unmodifiableMap(lastSavepoint.getNewResources());
+ newResources = getTransaction().getNewResources();
+ newObjects = getTransaction().getNewObjects();
+ dirtyObjects = getTransaction().getDirtyObjects();
+ detachedObjects = getTransaction().getDetachedObjects();
+ revisionDeltas = getTransaction().getRevisionDeltas();
+ newPackages = getTransaction().analyzeNewPackages();
}
- MultiMap.ListBased<CDOID, CDOResource> newResources = new MultiMap.ListBased<CDOID, CDOResource>();
- for (CDOSavepointImpl savepoint = lastSavepoint; savepoint != null; savepoint = savepoint.getPreviousSavepoint())
+ public Map<CDOID, CDOObject> getDirtyObjects()
{
- newResources.getDelegates().add(savepoint.getNewResources());
+ return dirtyObjects;
}
- return newResources;
- }
+ public Map<CDOID, CDOObject> getNewObjects()
+ {
+ return newObjects;
+ }
- /**
- * @since 2.0
- */
- public Map<CDOID, CDORevision> getBaseNewObjects()
- {
- if (lastSavepoint.getPreviousSavepoint() == null)
+ public List<CDOPackage> getNewPackages()
{
- return Collections.unmodifiableMap(lastSavepoint.getBaseNewObjects());
+ return newPackages;
}
- MultiMap.ListBased<CDOID, CDORevision> newObjects = new MultiMap.ListBased<CDOID, CDORevision>();
- for (CDOSavepointImpl savepoint = lastSavepoint; savepoint != null; savepoint = savepoint.getPreviousSavepoint())
+ public Map<CDOID, CDOResource> getNewResources()
{
- newObjects.getDelegates().add(savepoint.getBaseNewObjects());
+ return newResources;
}
- return newObjects;
- }
+ public Set<CDOID> getDetachedObjects()
+ {
+ return detachedObjects;
+ }
- public Map<CDOID, CDORevisionDelta> getRevisionDeltas()
- {
- if (lastSavepoint.getPreviousSavepoint() == null)
+ public Map<CDOID, CDORevisionDelta> getRevisionDeltas()
+ {
+ return revisionDeltas;
+ }
+
+ public CDOTransactionImpl getTransaction()
{
- return lastSavepoint.getRevisionDeltas();
+ return CDOTransactionImpl.this;
}
- // We need to combined the result for all delta in different Savepoint
- Map<CDOID, CDORevisionDelta> revisionDeltas = new ConcurrentHashMap<CDOID, CDORevisionDelta>();
- for (CDOSavepointImpl savepoint = firstSavepoint; savepoint != null; savepoint = savepoint.getNextSavepoint())
+ public void preCommit()
{
- for (Entry<CDOID, CDORevisionDelta> entry : savepoint.getRevisionDeltas().entrySet())
+ if (getTransaction().isDirty())
{
- // Skipping temporary
- if (entry.getKey().isTemporary())
+ if (TRACER.isEnabled())
{
- continue;
+ TRACER.trace("commit()");
}
- CDORevisionDeltaImpl revisionDelta = (CDORevisionDeltaImpl)revisionDeltas.get(entry.getKey());
- if (revisionDelta == null)
+ for (CDOTransactionHandler handler : getTransaction().getHandlers())
+ {
+ handler.committingTransaction(getTransaction());
+ }
+
+ try
+ {
+ preCommit(getNewResources());
+ preCommit(getNewObjects());
+ preCommit(getDirtyObjects());
+ }
+ catch (RuntimeException ex)
+ {
+ throw ex;
+ }
+ catch (Exception ex)
{
- revisionDeltas.put(entry.getKey(), entry.getValue());
+ throw new TransactionException(ex);
}
- else
+ }
+ }
+
+ public void postCommit(CommitTransactionResult result)
+ {
+ if (getTransaction().isDirty())
+ {
+ try
{
- for (CDOFeatureDelta delta : entry.getValue().getFeatureDeltas())
+ Collection<CDORevisionDelta> deltas = getRevisionDeltas().values();
+
+ postCommit(getNewResources(), result);
+ postCommit(getNewObjects(), result);
+ postCommit(getDirtyObjects(), result);
+
+ for (CDOID id : getDetachedObjects())
{
- if (delta instanceof CDOListFeatureDelta)
- {
- for (CDOFeatureDelta subDelta : ((CDOListFeatureDelta)delta).getListChanges())
- {
- revisionDelta.addFeatureDelta(subDelta);
- }
- }
- else
+ removeObject(id);
+ }
+
+ CDOSessionImpl session = getTransaction().getSession();
+
+ for (CDOPackage newPackage : newPackages)
+ {
+ ((InternalCDOPackage)newPackage).setPersistent(true);
+ }
+
+ getTransaction().getChangeSubscriptionManager().notifyDirtyObjects();
+
+ Map<CDOID, CDOObject> dirtyObjects = getDirtyObjects();
+ if (!dirtyObjects.isEmpty())
+ {
+ Set<CDOIDAndVersion> dirtyIDs = new HashSet<CDOIDAndVersion>();
+ for (CDOObject dirtyObject : dirtyObjects.values())
{
- revisionDelta.addFeatureDelta(delta);
+ CDORevision revision = dirtyObject.cdoRevision();
+ CDOIDAndVersion dirtyID = CDOIDUtil.createIDAndVersion(revision.getID(), revision.getVersion() - 1);
+ dirtyIDs.add(dirtyID);
}
+
+ session.handleCommitNotification(result.getTimeStamp(), dirtyIDs, getDetachedObjects(), deltas,
+ getTransaction());
}
+
+ getTransaction().cleanUp();
+ Map<CDOIDTemp, CDOID> idMappings = result.getIDMappings();
+ getTransaction().fireEvent(new FinishedEvent(CDOTransactionFinishedEvent.Type.COMMITTED, idMappings));
+ }
+ catch (RuntimeException ex)
+ {
+ throw ex;
+ }
+ catch (Exception ex)
+ {
+ throw new TransactionException(ex);
}
}
}
- return revisionDeltas;
+ @SuppressWarnings("unchecked")
+ private void preCommit(Map objects)
+ {
+ if (!objects.isEmpty())
+ {
+ for (Object object : objects.values())
+ {
+ ((InternalCDOObject)object).cdoInternalPreCommit();
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void postCommit(Map objects, CommitTransactionResult result)
+ {
+ if (!objects.isEmpty())
+ {
+ for (Object object : objects.values())
+ {
+ CDOStateMachine.INSTANCE.commit((InternalCDOObject)object, result);
+ }
+ }
+ }
}
/**
@@ -909,4 +1076,38 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction
getSource(), getConflictingObject(), isFirstConflict());
}
}
+
+ /**
+ * @author Eike Stepper
+ */
+ private final class ResourcesEvent extends Event implements CDOViewResourcesEvent
+ {
+ private static final long serialVersionUID = 1L;
+
+ private String resourcePath;
+
+ private Kind kind;
+
+ public ResourcesEvent(String resourcePath, Kind kind)
+ {
+ this.resourcePath = resourcePath;
+ this.kind = kind;
+ }
+
+ public String getResourcePath()
+ {
+ return resourcePath;
+ }
+
+ public Kind getKind()
+ {
+ return kind;
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("CDOViewResourcesEvent[source={0}, {1}={2}]", getSource(), resourcePath, kind);
+ }
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionStrategy.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionStrategy.java
new file mode 100644
index 0000000000..d81f8d5cb9
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionStrategy.java
@@ -0,0 +1,32 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo;
+
+import org.eclipse.emf.cdo.CDOSavepoint;
+
+/**
+ * @author Simon McDuff
+ * @since 2.0
+ */
+public interface CDOTransactionStrategy
+{
+ public static final CDOTransactionStrategy DEFAULT = CDOSingleTransactionStrategy.INSTANCE;
+
+ public void setTarget(InternalCDOTransaction transaction);
+
+ public void unsetTarget(InternalCDOTransaction transaction);
+
+ public void commit(InternalCDOTransaction transaction) throws Exception;
+
+ public void rollback(InternalCDOTransaction transaction, CDOSavepoint savepoint, boolean remote);
+
+ public CDOSavepoint setSavepoint(InternalCDOTransaction transaction);
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java
index 6975b0f36a..2869f20fa2 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java
@@ -13,6 +13,8 @@
* Simon McDuff - http://bugs.eclipse.org/202064
* Simon McDuff - http://bugs.eclipse.org/230832
* Simon McDuff - http://bugs.eclipse.org/233490
+ * Simon McDuff - http://bugs.eclipse.org/213402
+ * Simon McDuff - http://bugs.eclipse.org/204890
* Victor Roldan Betancort - http://bugs.eclipse.org/208689
**************************************************************************/
package org.eclipse.emf.internal.cdo;
@@ -22,7 +24,7 @@ import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.CDOView;
import org.eclipse.emf.cdo.CDOViewEvent;
-import org.eclipse.emf.cdo.CDOViewResourcesEvent;
+import org.eclipse.emf.cdo.CDOViewSet;
import org.eclipse.emf.cdo.analyzer.CDOFeatureAnalyzer;
import org.eclipse.emf.cdo.common.CDOProtocolConstants;
import org.eclipse.emf.cdo.common.id.CDOID;
@@ -30,6 +32,7 @@ import org.eclipse.emf.cdo.common.id.CDOIDAndVersion;
import org.eclipse.emf.cdo.common.id.CDOIDMeta;
import org.eclipse.emf.cdo.common.id.CDOIDObject;
import org.eclipse.emf.cdo.common.id.CDOIDProvider;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.model.CDOClass;
import org.eclipse.emf.cdo.common.model.CDOClassRef;
import org.eclipse.emf.cdo.common.revision.CDORevisionResolver;
@@ -37,11 +40,10 @@ import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.common.util.CDOException;
import org.eclipse.emf.cdo.common.util.TransportException;
import org.eclipse.emf.cdo.eresource.CDOResource;
-import org.eclipse.emf.cdo.eresource.EresourceFactory;
import org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl;
import org.eclipse.emf.cdo.query.CDOQuery;
import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
-import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.cdo.util.CDOURIUtil;
import org.eclipse.emf.cdo.util.ReadOnlyException;
import org.eclipse.emf.internal.cdo.bundle.OM;
@@ -59,15 +61,12 @@ import org.eclipse.net4j.util.ref.ReferenceValueMap;
import org.eclipse.net4j.util.transaction.TransactionException;
import org.eclipse.emf.common.notify.Adapter;
-import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.notify.impl.NotificationImpl;
-import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.InternalEObject;
-import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
@@ -85,8 +84,7 @@ import java.util.concurrent.ConcurrentMap;
/**
* @author Eike Stepper
*/
-public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implements CDOView, CDOIDProvider,
- Adapter.Internal
+public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implements CDOView, CDOIDProvider
{
private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_VIEW, CDOViewImpl.class);
@@ -94,7 +92,7 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
private CDOSessionImpl session;
- private ResourceSet resourceSet;
+ private CDOViewSet viewSet;
private boolean uniqueResourceContents = true;
@@ -146,7 +144,15 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
public ResourceSet getResourceSet()
{
- return resourceSet;
+ return viewSet.getResourceSet();
+ }
+
+ /**
+ * @since 2.0
+ */
+ public CDOViewSet getViewSet()
+ {
+ return viewSet;
}
public CDOSessionImpl getSession()
@@ -258,6 +264,12 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
{
try
{
+ CDOResource resource = getResource(path, false);
+ if (resource != null && resource.cdoID() != null)
+ {
+ return resource.cdoID();
+ }
+
IFailOverStrategy failOverStrategy = session.getFailOverStrategy();
ResourceIDRequest request = new ResourceIDRequest(session.getChannel(), path);
return failOverStrategy.send(request);
@@ -279,10 +291,21 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
}
}
+ /**
+ * @since 2.0
+ */
public CDOResource getResource(String path)
{
- URI uri = CDOUtil.createResourceURI(path);
- return (CDOResource)getResourceSet().getResource(uri, true);
+ return getResource(path, true);
+ }
+
+ /**
+ * @since 2.0
+ */
+ public CDOResource getResource(String path, boolean loadInDemand)
+ {
+ URI uri = CDOURIUtil.createResourceURI(this, path);
+ return (CDOResource)getResourceSet().getResource(uri, loadInDemand);
}
/**
@@ -298,22 +321,13 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
{
if (resourceID == null || resourceID.isNull())
{
- throw new IllegalArgumentException("resourceID == null || resourceID == CDOID.NULL");
+ throw new IllegalArgumentException("resourceID == null || resourceID.isNull()");
}
- // TODO What about simply looking in the objects cache of this view as well?
- ResourceSet resourceSet = getResourceSet();
- EList<Resource> resources = resourceSet.getResources();
- for (Resource resource : resources)
+ CDOResourceImpl resource = (CDOResourceImpl)getObject(resourceID);
+ if (resource != null)
{
- if (resource instanceof CDOResourceImpl)
- {
- CDOResourceImpl cdoResource = (CDOResourceImpl)resource;
- if (resourceID.equals(cdoResource.cdoID()))
- {
- return cdoResource;
- }
- }
+ return resource;
}
try
@@ -335,8 +349,9 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
public CDOResourceImpl addResource(CDOID id, String path)
{
- CDOResourceImpl resource = (CDOResourceImpl)EresourceFactory.eINSTANCE.createCDOResource();
- resource.setPath(path);
+ URI createURI = CDOURIUtil.createResourceURI(this, path);
+ CDOResourceImpl resource = (CDOResourceImpl)viewSet.getResourceFactory().createResource(createURI);
+ resource.setURI(createURI);
InternalCDOObject resourceObject = resource;
resourceObject.cdoInternalSetID(id);
@@ -377,6 +392,9 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
return getObject(id, false);
}
+ /**
+ * Support recursivity and concurrency.
+ */
public InternalCDOObject getObject(CDOID id, boolean loadOnDemand)
{
if (id == null || id.isNull())
@@ -391,29 +409,31 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
return lastLookupObject;
}
- lastLookupID = id;
- lastLookupObject = objects.get(id);
- if (lastLookupObject == null)
+ // Needed for recursive call to getObject. (from createObject/cleanObject/getResource/getObject)
+ InternalCDOObject localLookupObject = objects.get(id);
+ if (localLookupObject == null)
{
if (id.isMeta())
{
- lastLookupObject = createMetaObject((CDOIDMeta)id);
+ localLookupObject = createMetaObject((CDOIDMeta)id);
}
else
{
if (loadOnDemand)
{
- lastLookupObject = createObject(id);
+ localLookupObject = createObject(id);
}
else
{
- lastLookupObject = createProxy(id);
+ localLookupObject = createProxy(id);
}
}
- registerObject(lastLookupObject);
+ registerObject(localLookupObject);
}
+ lastLookupID = id;
+ lastLookupObject = localLookupObject;
return lastLookupObject;
}
}
@@ -497,6 +517,24 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
InternalCDORevision revision = getRevision(id, true);
CDOClass cdoClass = revision.getCDOClass();
InternalCDOObject object = newInstance(cdoClass);
+ cleanObject(object, revision);
+ return object;
+ }
+
+ public void registerProxyResource(CDOResourceImpl resource)
+ {
+ resource.cdoInternalSetResource(resource);
+ resource.cdoInternalSetView(this);
+ resource.cdoInternalSetID(getResourceID(resource.getPath()));
+ resource.cdoInternalSetState(CDOState.PROXY);
+ registerObject(resource);
+ }
+
+ /**
+ * @since 2.0
+ */
+ protected void cleanObject(InternalCDOObject object, InternalCDORevision revision)
+ {
if (object instanceof CDOResourceImpl)
{
object.cdoInternalSetResource((CDOResourceImpl)object);
@@ -516,7 +554,6 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
object.cdoInternalSetID(revision.getID());
object.cdoInternalSetState(CDOState.CLEAN);
object.cdoInternalPostLoad();
- return object;
}
private InternalCDOObject createProxy(CDOID id)
@@ -571,12 +608,31 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
return id;
}
+ else if (idOrObject instanceof InternalEObject)
+ {
+ InternalEObject eObject = (InternalEObject)idOrObject;
+ String uri = EcoreUtil.getURI(eObject).toString();
+ if (eObject instanceof InternalCDOObject)
+ {
+ InternalCDOObject object = (InternalCDOObject)idOrObject;
+ if (object.cdoView() != null && FSMUtil.isNew(object))
+ {
+ return CDOIDUtil.createExternalTemp(uri);
+ }
+ }
+ return CDOIDUtil.createExternal(uri);
+ }
throw new IllegalStateException("Unable to provideCDOID: " + idOrObject.getClass().getName());
}
public Object convertObjectToID(Object potentialObject)
{
+ return convertObjectToID(potentialObject, false);
+ }
+
+ public Object convertObjectToID(Object potentialObject, boolean onlyPersistedID)
+ {
if (potentialObject instanceof CDOID)
{
return potentialObject;
@@ -585,17 +641,24 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
if (potentialObject instanceof InternalEObject && !(potentialObject instanceof InternalCDOObject))
{
InternalEObject eObject = (InternalEObject)potentialObject;
- InternalCDOObject adapter = FSMUtil.adapt(eObject, this);
- if (adapter != null)
+
+ // Only adapt object that are already adapted.
+ // We do not want to create a attach without goign through the normal process.
+ if (EcoreUtil.getAdapter(eObject.eAdapters(), CDOAdapterImpl.class) != null)
{
- potentialObject = adapter;
+ InternalCDOObject adapter = FSMUtil.adapt(eObject, this);
+ if (adapter != null)
+ {
+ potentialObject = adapter;
+ }
}
}
if (potentialObject instanceof InternalCDOObject)
{
InternalCDOObject object = (InternalCDOObject)potentialObject;
- if (object.cdoView() == this)
+ boolean newOrTransient = FSMUtil.isTransient(object) || FSMUtil.isNew(object);
+ if (object.cdoView() == this && (!onlyPersistedID || !newOrTransient))
{
return object.cdoID();
}
@@ -614,6 +677,11 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
}
CDOID id = (CDOID)potentialID;
+ if (id.isExternal())
+ {
+ return getResourceSet().getEObject(URI.createURI(id.toURIFragment()), true);
+ }
+
InternalCDOObject result = getObject(id, true);
if (result == null)
{
@@ -690,7 +758,7 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
* dirtyOIDs set to be unmodifiable. It does not wrap the set (again).
* @since 2.0
*/
- public void handleInvalidation(long timeStamp, Set<CDOIDAndVersion> dirtyOIDs)
+ public void handleInvalidation(long timeStamp, Set<CDOIDAndVersion> dirtyOIDs, Collection<CDOID> detachedObjects)
{
List<InternalCDOObject> dirtyObjects = invalidationNotificationsEnabled ? new ArrayList<InternalCDOObject>() : null;
for (CDOIDAndVersion dirtyOID : dirtyOIDs)
@@ -711,6 +779,15 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
}
}
+ for (CDOID id : detachedObjects)
+ {
+ InternalCDOObject cdoObject = removeObject(id);
+ if (cdoObject != null)
+ {
+ CDOStateMachine.INSTANCE.invalidate(cdoObject, true, timeStamp);
+ }
+ }
+
if (dirtyObjects != null)
{
for (InternalCDOObject dirtyObject : dirtyObjects)
@@ -826,160 +903,15 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
public Notifier getTarget()
{
- return resourceSet;
- }
-
- public void setTarget(Notifier newTarget)
- {
- ResourceSet resourceSet = (ResourceSet)newTarget;
- if (TRACER.isEnabled())
- {
- TRACER.trace("Attaching CDO view to " + resourceSet);
- }
-
- this.resourceSet = resourceSet;
- for (Resource resource : resourceSet.getResources())
- {
- if (resource instanceof CDOResourceImpl)
- {
- CDOResourceImpl cdoResource = (CDOResourceImpl)resource;
- notifyAdd(cdoResource);
- }
- }
- }
-
- public void unsetTarget(Notifier oldTarget)
- {
- ResourceSet resourceSet = (ResourceSet)oldTarget;
- for (Resource resource : resourceSet.getResources())
- {
- if (resource instanceof CDOResourceImpl)
- {
- CDOResourceImpl cdoResource = (CDOResourceImpl)resource;
- notifyRemove(cdoResource);
- }
- }
-
- if (TRACER.isEnabled())
- {
- TRACER.trace("Detaching CDO view from " + resourceSet);
- }
-
- if (resourceSet == oldTarget)
- {
- setTarget(null);
- }
- }
-
- public void notifyChanged(Notification msg)
- {
- try
- {
- switch (msg.getEventType())
- {
- case Notification.ADD:
- notifyAdd(msg);
- break;
-
- case Notification.ADD_MANY:
- notifyAddMany(msg);
- break;
-
- case Notification.REMOVE:
- notifyRemove(msg);
- break;
-
- case Notification.REMOVE_MANY:
- notifyRemoveMany(msg);
- break;
- }
- }
- catch (RuntimeException ex)
- {
- OM.LOG.error(ex);
- throw ex;
- }
- }
-
- private void notifyAdd(Notification msg)
- {
- if (msg.getNewValue() instanceof CDOResourceImpl)
- {
- notifyAdd((CDOResourceImpl)msg.getNewValue());
- }
+ return getResourceSet();
}
- @SuppressWarnings("unchecked")
- private void notifyAddMany(Notification msg)
- {
- EList<Resource> newResources = (EList<Resource>)msg.getNewValue();
- EList<Resource> oldResources = (EList<Resource>)msg.getOldValue();
- for (Resource newResource : newResources)
- {
- if (newResource instanceof CDOResourceImpl)
- {
- if (!oldResources.contains(newResource))
- {
- notifyAdd((CDOResourceImpl)newResource);
- }
- }
- }
- }
-
- private void notifyAdd(CDOResourceImpl cdoResource)
- {
- try
- {
- CDOStateMachine.INSTANCE.attach(cdoResource, cdoResource, this);
- fireEvent(new ResourcesEvent(cdoResource.getPath(), ResourcesEvent.Kind.ADDED));
- }
- catch (RuntimeException ex)
- {
- OM.LOG.error(ex);
-
- try
- {
- ((InternalCDOObject)cdoResource).cdoInternalSetState(CDOState.NEW);
- resourceSet.getResources().remove(cdoResource);
- }
- catch (RuntimeException ignore)
- {
- }
-
- throw ex;
- }
- }
-
- private void notifyRemove(Notification msg)
- {
- if (msg.getOldValue() instanceof CDOResourceImpl)
- {
- notifyRemove((CDOResourceImpl)msg.getOldValue());
- }
- }
-
- @SuppressWarnings("unchecked")
- private void notifyRemoveMany(Notification msg)
- {
- EList<Resource> newResources = (EList<Resource>)msg.getNewValue();
- EList<Resource> oldResources = (EList<Resource>)msg.getOldValue();
- for (Resource oldResource : oldResources)
- {
- if (oldResource instanceof CDOResourceImpl)
- {
- if (!newResources.contains(oldResource))
- {
- // TODO Optimize event notification with IContainerEvent
- notifyRemove((CDOResourceImpl)oldResource);
- }
- }
- }
- }
-
- private void notifyRemove(CDOResourceImpl cdoResource)
+ /**
+ * @since 2.0
+ */
+ public void setViewSet(CDOViewSet viewSet)
{
- CDOStateMachine.INSTANCE.detach(cdoResource);
- fireEvent(new ResourcesEvent(cdoResource.getPath(), ResourcesEvent.Kind.REMOVED));
+ this.viewSet = viewSet;
}
/**
@@ -1001,40 +933,6 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
}
/**
- * @author Eike Stepper
- */
- private final class ResourcesEvent extends Event implements CDOViewResourcesEvent
- {
- private static final long serialVersionUID = 1L;
-
- private String resourcePath;
-
- private Kind kind;
-
- public ResourcesEvent(String resourcePath, Kind kind)
- {
- this.resourcePath = resourcePath;
- this.kind = kind;
- }
-
- public String getResourcePath()
- {
- return resourcePath;
- }
-
- public Kind getKind()
- {
- return kind;
- }
-
- @Override
- public String toString()
- {
- return MessageFormat.format("CDOViewResourcesEvent[source={0}, {1}={2}]", getSource(), resourcePath, kind);
- }
- }
-
- /**
* @author Simon McDuff
* @since 2.0
*/
@@ -1207,4 +1105,5 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement
subscribe(eObject, adapter, -1);
}
}
+
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewSetImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewSetImpl.java
new file mode 100644
index 0000000000..abbd800759
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewSetImpl.java
@@ -0,0 +1,314 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ * Simon McDuff - http://bugs.eclipse.org/246619
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo;
+
+import org.eclipse.emf.cdo.CDOView;
+import org.eclipse.emf.cdo.CDOViewSet;
+import org.eclipse.emf.cdo.common.CDOProtocolConstants;
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.eresource.impl.CDOResourceFactoryImpl;
+import org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl;
+import org.eclipse.emf.cdo.util.CDOURIUtil;
+
+import org.eclipse.emf.internal.cdo.bundle.OM;
+import org.eclipse.emf.internal.cdo.util.CDOViewSetPackageRegistryImpl;
+import org.eclipse.emf.internal.cdo.util.FSMUtil;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.notify.impl.NotificationImpl;
+import org.eclipse.emf.common.notify.impl.NotifierImpl;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.Resource.Factory.Registry;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+/**
+ * @author Simon McDuff
+ * @since 2.0
+ */
+public class CDOViewSetImpl extends NotifierImpl implements CDOViewSet, Adapter
+{
+ private Set<CDOViewImpl> views = new HashSet<CDOViewImpl>();
+
+ private Map<String, CDOViewImpl> mapOfViews = new HashMap<String, CDOViewImpl>();
+
+ private ResourceSet resourceSet;
+
+ private CDOResourceFactoryImpl resourceFactory = new CDOResourceFactoryImpl(this);
+
+ private CDOViewSetPackageRegistryImpl packageRegistry = new CDOViewSetPackageRegistryImpl(this);
+
+ public CDOViewSetImpl()
+ {
+ }
+
+ public ResourceSet getResourceSet()
+ {
+ return resourceSet;
+ }
+
+ public EPackage.Registry getPackageRegistry()
+ {
+ return packageRegistry;
+ }
+
+ public CDOResourceFactoryImpl getResourceFactory()
+ {
+ return resourceFactory;
+ }
+
+ public CDOView[] getViews()
+ {
+ synchronized (views)
+ {
+ return views.toArray(new CDOView[views.size()]);
+ }
+ }
+
+ /**
+ * @throws IllegalArgumentException
+ * if repositoryUUID doesn't match any CDOView.
+ */
+ public CDOViewImpl resolveUUID(String repositoryUUID)
+ {
+ CDOViewImpl view = null;
+
+ synchronized (views)
+ {
+ view = mapOfViews.get(repositoryUUID);
+
+ if (view == null)
+ {
+ if (repositoryUUID != null)
+ {
+ throw new IllegalArgumentException("Cannot find associate CDOView for reposUUID " + repositoryUUID);
+ }
+
+ if (mapOfViews.size() == 1)
+ {
+ return views.iterator().next();
+ }
+
+ if (mapOfViews.size() == 0)
+ {
+ return null;
+ }
+
+ throw new IllegalStateException("Don't know which CDOView to take since no authority has been specified");
+ }
+ }
+ return view;
+ }
+
+ public CDOViewImpl getView(String repositoryUUID)
+ {
+ synchronized (views)
+ {
+ return mapOfViews.get(repositoryUUID);
+ }
+ }
+
+ public void add(CDOViewImpl view)
+ {
+ synchronized (views)
+ {
+ CDOView lookupView = mapOfViews.get(view.getSession().getRepositoryUUID());
+ if (lookupView != null)
+ {
+ throw new RuntimeException("Only one view/transaction per repository can be open for the same resource set");
+ }
+
+ views.add(view);
+ mapOfViews.put(view.getSession().getRepositoryUUID(), view);
+
+ if (views.size() == 1)
+ {
+ initializeResources(view);
+ }
+ }
+
+ if (eNotificationRequired())
+ {
+ NotificationImpl notification = new NotificationImpl(NotificationImpl.ADD, null, view);
+ eNotify(notification);
+ }
+ }
+
+ private void initializeResources(CDOView cdoView)
+ {
+ // Intialize the resourceset correctly when it get connected to the first time to a view.
+ for (Resource resource : resourceSet.getResources())
+ {
+ if (resource instanceof CDOResourceImpl)
+ {
+ CDOResourceImpl cdoResource = (CDOResourceImpl)resource;
+ if (cdoResource.cdoView() == null)
+ {
+ URI newURI = CDOURIUtil.createResourceURI(cdoView, cdoResource.getPath());
+ cdoResource.setURI(newURI);
+ notifyAdd(cdoResource);
+ }
+ }
+ }
+ }
+
+ public void remove(CDOViewImpl view)
+ {
+ List<Resource> resToRemove = new ArrayList<Resource>();
+ synchronized (views)
+ {
+ // It is important to remove view from the list first. It is the way we can differentiate close and detach.
+ views.remove(view);
+ mapOfViews.remove(view.getSession().getRepositoryUUID());
+
+ for (Resource resource : getResourceSet().getResources())
+ {
+ if (resource instanceof CDOResource)
+ {
+ CDOResource cdoRes = (CDOResource)resource;
+ if (cdoRes.cdoView() == view)
+ {
+ resToRemove.add(resource);
+ }
+ }
+ }
+ }
+
+ getResourceSet().getResources().removeAll(resToRemove);
+ if (eNotificationRequired())
+ {
+ NotificationImpl notification = new NotificationImpl(NotificationImpl.REMOVE, view, null);
+ eNotify(notification);
+ }
+ }
+
+ public Notifier getTarget()
+ {
+ return resourceSet;
+ }
+
+ public void setTarget(Notifier newTarget)
+ {
+ if (resourceSet != null)
+ {
+ throw new IllegalStateException("Cannot associate more than 1 resourceset to this viewset");
+ }
+ if (isAdapterForType(newTarget))
+ {
+ resourceSet = (ResourceSet)newTarget;
+ EPackage.Registry oldPackageRegistry = resourceSet.getPackageRegistry();
+ resourceSet.setPackageRegistry(getPackageRegistry());
+ for (Entry<String, Object> entry : oldPackageRegistry.entrySet())
+ {
+ getPackageRegistry().put(entry.getKey(), entry.getValue());
+ }
+ Registry registry = resourceSet.getResourceFactoryRegistry();
+ Map<String, Object> map = registry.getProtocolToFactoryMap();
+ map.put(CDOProtocolConstants.PROTOCOL_NAME, getResourceFactory());
+ }
+ else
+ {
+ throw new IllegalArgumentException("Doesn't support " + newTarget);
+ }
+ }
+
+ public boolean isAdapterForType(Object type)
+ {
+ return type instanceof ResourceSet;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void notifyChanged(Notification notification)
+ {
+ try
+ {
+ switch (notification.getEventType())
+ {
+ case Notification.ADD:
+ if (notification.getNewValue() instanceof CDOResourceImpl)
+ {
+ notifyAdd((CDOResourceImpl)notification.getNewValue());
+ }
+ break;
+
+ case Notification.ADD_MANY:
+ {
+ List<Resource> newResources = (List<Resource>)notification.getNewValue();
+ for (Resource newResource : newResources)
+ {
+ if (newResource instanceof CDOResourceImpl)
+ {
+ notifyAdd((CDOResourceImpl)newResource);
+ }
+ }
+ }
+ break;
+
+ case Notification.REMOVE:
+ if (notification.getOldValue() instanceof CDOResourceImpl)
+ {
+ notifyRemove((CDOResourceImpl)notification.getOldValue());
+ }
+ break;
+
+ case Notification.REMOVE_MANY:
+ {
+ List<Resource> resources = (List<Resource>)notification.getOldValue();
+ for (Resource oldResource : resources)
+ {
+ if (oldResource instanceof CDOResourceImpl)
+ {
+ notifyRemove((CDOResourceImpl)oldResource);
+ }
+ }
+ }
+ break;
+ }
+ }
+ catch (RuntimeException ex)
+ {
+ OM.LOG.error(ex);
+ throw ex;
+ }
+ }
+
+ /**
+ * Only generates event to CDOView if it is a new CDOResource.
+ */
+ private void notifyAdd(CDOResourceImpl resourceImpl)
+ {
+ CDOViewImpl view = resolveUUID(resourceImpl.getURI().authority());
+ if (view != null && FSMUtil.isTransient(resourceImpl))
+ {
+ view.toTransaction().attach(resourceImpl);
+ }
+ }
+
+ /**
+ *
+ */
+ private void notifyRemove(CDOResourceImpl resourceImpl)
+ {
+ // Don't do anything
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOXASavepoint.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOXASavepoint.java
new file mode 100644
index 0000000000..8f87a249bd
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOXASavepoint.java
@@ -0,0 +1,41 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo;
+
+import org.eclipse.emf.cdo.CDOSavepoint;
+import org.eclipse.emf.cdo.CDOUserTransaction;
+
+import java.util.List;
+
+/**
+ * @author Simon McDuff
+ * @since 2.0
+ */
+public class CDOXASavepoint extends CDOAbstractSavepoint
+{
+ private List<CDOSavepoint> savepoints;
+
+ public CDOXASavepoint(CDOUserTransaction transaction, CDOAbstractSavepoint lastSavepoint)
+ {
+ super(transaction, lastSavepoint);
+
+ }
+
+ public List<CDOSavepoint> getSavepoints()
+ {
+ return savepoints;
+ }
+
+ public void setSavepoints(List<CDOSavepoint> savepoints)
+ {
+ this.savepoints = savepoints;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOXATransactionCommitContext.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOXATransactionCommitContext.java
new file mode 100644
index 0000000000..245045fe11
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOXATransactionCommitContext.java
@@ -0,0 +1,156 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo;
+
+import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDProvider;
+import org.eclipse.emf.cdo.common.model.CDOPackage;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.internal.common.id.CDOIDExternalTempImpl;
+
+import org.eclipse.emf.internal.cdo.CDOXATransactionImpl.CDOXAState;
+import org.eclipse.emf.internal.cdo.protocol.CommitTransactionResult;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+/**
+ * @author Simon McDuff
+ * @since 2.0
+ */
+public class CDOXATransactionCommitContext implements Callable<Object>, CDOIDProvider, CDOCommitContext
+{
+ private CDOXATransactionImpl transactionManager;
+
+ private CDOXAState state;
+
+ private CommitTransactionResult result;
+
+ private CDOCommitContext delegateCommitContext;
+
+ private Map<CDOIDExternalTempImpl, InternalCDOTransaction> requestedIDs = new HashMap<CDOIDExternalTempImpl, InternalCDOTransaction>();
+
+ public CDOXATransactionCommitContext(CDOXATransactionImpl manager, CDOCommitContext commitContext)
+ {
+ transactionManager = manager;
+ delegateCommitContext = commitContext;
+ }
+
+ public CDOXATransactionImpl getTransactionManager()
+ {
+ return transactionManager;
+ }
+
+ public CDOXAState getState()
+ {
+ return state;
+ }
+
+ public void setState(CDOXAState state)
+ {
+ this.state = state;
+ }
+
+ public CommitTransactionResult getResult()
+ {
+ return result;
+ }
+
+ public void setResult(CommitTransactionResult result)
+ {
+ this.result = result;
+ }
+
+ public InternalCDOTransaction getTransaction()
+ {
+ return delegateCommitContext.getTransaction();
+ }
+
+ public Map<CDOIDExternalTempImpl, InternalCDOTransaction> getRequestedIDs()
+ {
+ return requestedIDs;
+ }
+
+ public Map<CDOID, CDOObject> getDirtyObjects()
+ {
+ return delegateCommitContext.getDirtyObjects();
+ }
+
+ public Map<CDOID, CDOObject> getNewObjects()
+ {
+ return delegateCommitContext.getNewObjects();
+ }
+
+ public List<CDOPackage> getNewPackages()
+ {
+ return delegateCommitContext.getNewPackages();
+ }
+
+ public Map<CDOID, CDOResource> getNewResources()
+ {
+ return delegateCommitContext.getNewResources();
+ }
+
+ public Set<CDOID> getDetachedObjects()
+ {
+ return delegateCommitContext.getDetachedObjects();
+ }
+
+ public Map<CDOID, CDORevisionDelta> getRevisionDeltas()
+ {
+ return delegateCommitContext.getRevisionDeltas();
+ }
+
+ public Object call() throws Exception
+ {
+ state.handle(this);
+ return true;
+ }
+
+ public CDOID provideCDOID(Object idOrObject)
+ {
+ CDOID id = getTransaction().provideCDOID(idOrObject);
+
+ if (id instanceof CDOIDExternalTempImpl)
+ {
+ CDOIDExternalTempImpl proxyTemp = (CDOIDExternalTempImpl)id;
+ if (!requestedIDs.containsKey(proxyTemp))
+ {
+ ResourceSet resourceSet = getTransaction().getResourceSet();
+ URI uri = URI.createURI(proxyTemp.toURIFragment());
+ InternalCDOObject object = (InternalCDOObject)resourceSet.getEObject(uri, true);
+ InternalCDOTransaction cdoTransaction = (InternalCDOTransaction)object.cdoView();
+ getTransactionManager().add(cdoTransaction, proxyTemp);
+ requestedIDs.put(proxyTemp, cdoTransaction);
+ }
+ }
+
+ return id;
+ }
+
+ public void preCommit()
+ {
+ delegateCommitContext.preCommit();
+ }
+
+ public void postCommit(CommitTransactionResult result)
+ {
+ delegateCommitContext.postCommit(result);
+ }
+};
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOXATransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOXATransactionImpl.java
new file mode 100644
index 0000000000..545256b1db
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOXATransactionImpl.java
@@ -0,0 +1,606 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo;
+
+import org.eclipse.emf.cdo.CDOSavepoint;
+import org.eclipse.emf.cdo.CDOSession;
+import org.eclipse.emf.cdo.CDOTransaction;
+import org.eclipse.emf.cdo.CDOView;
+import org.eclipse.emf.cdo.CDOViewSet;
+import org.eclipse.emf.cdo.CDOXATransaction;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.util.CDOUtil;
+
+import org.eclipse.emf.internal.cdo.protocol.CommitTransactionCancelRequest;
+import org.eclipse.emf.internal.cdo.protocol.CommitTransactionPhase1Request;
+import org.eclipse.emf.internal.cdo.protocol.CommitTransactionPhase2Request;
+import org.eclipse.emf.internal.cdo.protocol.CommitTransactionPhase3Request;
+import org.eclipse.emf.internal.cdo.protocol.CommitTransactionResult;
+
+import org.eclipse.net4j.channel.IChannel;
+import org.eclipse.net4j.signal.failover.IFailOverStrategy;
+import org.eclipse.net4j.util.transaction.TransactionException;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.Notifier;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+/**
+ * Three-phase commit.
+ * <p>
+ * Phase 1 does the following for each CDOTransaction:<br>
+ * - preCommit <br>
+ * - Accumulate external temporary ID.<br>
+ * - request the commit to the server.<br>
+ * - The server registers the commit context and returns the final ID for each temporary ID.
+ * <p>
+ * Phase 2 does the following for each CDOTransaction:<br>
+ * - Transfer to the server a list of mapping of temporary externalID and final external ID that we accumulate
+ * previously<br>
+ * - Returns to the client only when commit process is ready to flush to disk (commit). <br>
+ * <p>
+ * Phase 3 does the following for each CDOTransaction:<br>
+ * - Make modifications permanent.<br>
+ * - PostCommit.
+ * <p>
+ * If an exception occurred during phase 1 or phase 2, the commit will be cancelled for all {@link CDOTransaction}
+ * include in the XA transaction. If an exception occurred during phase 3, the commit will be cancelled only for the
+ * {@link CDOTransaction} where the error happened.
+ * <p>
+ * All {@link CDOTransaction} includes in the commit process need to have finish their phase before moving to the next
+ * phase. For one phase, every {@link CDOTransaction} could have their own thread. It depends of the ExecutorService.
+ * <p>
+ *
+ * @author Simon McDuff
+ * @since 2.0
+ */
+public class CDOXATransactionImpl implements CDOXATransaction
+{
+ private List<InternalCDOTransaction> views = new ArrayList<InternalCDOTransaction>();
+
+ private boolean allRequestEnabled = true;
+
+ private ExecutorService executorService = Executors.newFixedThreadPool(10);
+
+ private Map<InternalCDOTransaction, CDOXATransactionCommitContext> activeContext = new HashMap<InternalCDOTransaction, CDOXATransactionCommitContext>();
+
+ private Map<InternalCDOTransaction, Set<CDOID>> requestedCDOID = new HashMap<InternalCDOTransaction, Set<CDOID>>();
+
+ private CDOXASavepoint lastSavepoint = new CDOXASavepoint(this, null);
+
+ private CDOXASavepoint firstSavepoint = lastSavepoint;
+
+ private CDOTransactionStrategy transactionStrategy = new CDOXATransactionStrategyImpl();
+
+ private CDOXAInternalAdapter internalAdapter = new CDOXAInternalAdapter();
+
+ public CDOXATransactionImpl()
+ {
+ }
+
+ public boolean isAllowRequestFromTransactionEnabled()
+ {
+ return allRequestEnabled;
+ }
+
+ public void setAllowRequestFromTransactionEnabled(boolean allRequest)
+ {
+ allRequestEnabled = allRequest;
+ }
+
+ public void add(InternalCDOTransaction transaction)
+ {
+ transaction.setTransactionStrategy(transactionStrategy);
+ }
+
+ public void remove(InternalCDOTransaction transaction)
+ {
+ transaction.setTransactionStrategy(null);
+ }
+
+ synchronized public void add(CDOViewSet viewSet)
+ {
+ CDOXATransaction transSet = CDOUtil.getXATransaction(viewSet);
+ if (transSet != null)
+ {
+ throw new IllegalArgumentException("XATransaction is already attached to this viewSet");
+ }
+
+ viewSet.eAdapters().add(internalAdapter);
+
+ for (InternalCDOTransaction transaction : getTransactions(viewSet))
+ {
+ add(transaction);
+ }
+ }
+
+ synchronized public void remove(CDOViewSet viewSet)
+ {
+ CDOXATransaction transSet = CDOUtil.getXATransaction(viewSet);
+ if (transSet != this)
+ {
+ throw new IllegalArgumentException("ViewSet isn't attached to this XATransaction");
+ }
+
+ for (InternalCDOTransaction transaction : getTransactions(viewSet))
+ {
+ remove(transaction);
+ }
+
+ viewSet.eAdapters().remove(internalAdapter);
+ };
+
+ public void add(InternalCDOTransaction view, CDOID object)
+ {
+ synchronized (requestedCDOID)
+ {
+ Set<CDOID> ids = requestedCDOID.get(view);
+ if (ids == null)
+ {
+ ids = new HashSet<CDOID>();
+ requestedCDOID.put(view, ids);
+ }
+
+ ids.add(object);
+ }
+ }
+
+ public CDOID[] get(InternalCDOTransaction transaction)
+ {
+ Set<CDOID> ids = requestedCDOID.get(transaction);
+ return ids.toArray(new CDOID[ids.size()]);
+ }
+
+ public CDOXATransactionCommitContext getCommitContext(CDOTransaction transaction)
+ {
+ return activeContext.get(transaction);
+ }
+
+ private void send(Collection<CDOXATransactionCommitContext> xaTransactions) throws InterruptedException,
+ ExecutionException
+ {
+ List<Future<Object>> futures = new ArrayList<Future<Object>>();
+ for (CDOXATransactionCommitContext xaTransaction : xaTransactions)
+ {
+ futures.add(executorService.submit(xaTransaction));
+ }
+
+ for (Future<Object> future : futures)
+ {
+ future.get();
+ }
+ }
+
+ private void cleanUp()
+ {
+ activeContext.clear();
+ requestedCDOID.clear();
+ }
+
+ private List<InternalCDOTransaction> getTransactions(CDOViewSet viewSet)
+ {
+ List<InternalCDOTransaction> transactions = new ArrayList<InternalCDOTransaction>();
+ for (CDOView view : viewSet.getViews())
+ {
+ if (view instanceof InternalCDOTransaction)
+ {
+ transactions.add((InternalCDOTransaction)view);
+ }
+ }
+
+ return transactions;
+ }
+
+ public void commit() throws TransactionException
+ {
+ int phase = 0;
+ try
+ {
+ CDOXAState defaultState = CDOXAPhase1State.INSTANCE;
+
+ /*
+ * if (transactions.size() == 1) { defaultState = CDOXAALLPhaseState.INSTANCE; }
+ */
+ for (InternalCDOTransaction transaction : views)
+ {
+ CDOXATransactionCommitContext xaTransaction = new CDOXATransactionCommitContext(this, transaction
+ .createCommitContext());
+ xaTransaction.setState(defaultState);
+ activeContext.put(transaction, xaTransaction);
+ }
+
+ // We need to complete 3 phases
+ for (phase = 0; phase < 3; phase++)
+ {
+ send(activeContext.values());
+ }
+ }
+ catch (Exception ex)
+ {
+ if (phase < 2)
+ {
+ // Phase 0 and 1 are the only two phases we can cancel.
+ for (CDOXATransactionCommitContext transaction : activeContext.values())
+ {
+ transaction.setState(CDOXACancel.INSTANCE);
+ }
+
+ try
+ {
+ send(activeContext.values());
+ }
+ catch (InterruptedException ignore)
+ {
+ }
+ catch (ExecutionException ignore)
+ {
+ }
+ }
+
+ throw new TransactionException(ex);
+ }
+ finally
+ {
+ cleanUp();
+ }
+ }
+
+ public CDOXASavepoint getLastSavepoint()
+ {
+ return lastSavepoint;
+ }
+
+ public void rollback(boolean remote)
+ {
+ rollback(firstSavepoint, true);
+ }
+
+ public void rollback()
+ {
+ rollback(true);
+ }
+
+ public void rollback(CDOSavepoint savepoint)
+ {
+ rollback(savepoint, true);
+ }
+
+ public void rollback(CDOSavepoint savepoint, boolean remote)
+ {
+ if (savepoint == null)
+ {
+ throw new IllegalArgumentException("Save point is null");
+ }
+
+ if (savepoint.getUserTransaction() != this)
+ {
+ throw new IllegalArgumentException("Save point to rollback doesn't belong to this transaction: " + savepoint);
+ }
+
+ if (!savepoint.isValid())
+ {
+ throw new IllegalArgumentException("Savepoint isn't valid : " + savepoint);
+ }
+
+ CDOXASavepoint savepointSet = (CDOXASavepoint)savepoint;
+ List<CDOSavepoint> savepoints = savepointSet.getSavepoints();
+ if (savepoints == null)
+ {
+ savepoints = getListSavepoints();
+ }
+
+ for (CDOSavepoint indexSavePoint : savepoints)
+ {
+ InternalCDOTransaction transaction = (InternalCDOTransaction)indexSavePoint.getUserTransaction();
+ CDOSingleTransactionStrategy.INSTANCE.rollback(transaction, indexSavePoint, remote);
+ }
+
+ lastSavepoint = savepointSet;
+ lastSavepoint.setNextSavepoint(null);
+ lastSavepoint.setSavepoints(null);
+ }
+
+ public CDOSavepoint setSavepoint()
+ {
+ List<CDOSavepoint> savepoints = getListSavepoints();
+ for (CDOSavepoint savepoint : savepoints)
+ {
+ InternalCDOTransaction transaction = (InternalCDOTransaction)savepoint.getUserTransaction();
+ CDOSingleTransactionStrategy.INSTANCE.setSavepoint(transaction);
+ }
+
+ getLastSavepoint().setSavepoints(savepoints);
+ lastSavepoint = new CDOXASavepoint(this, getLastSavepoint());
+ return lastSavepoint;
+ }
+
+ private List<CDOSavepoint> getListSavepoints()
+ {
+ synchronized (views)
+ {
+ List<CDOSavepoint> savepoints = new ArrayList<CDOSavepoint>();
+ for (InternalCDOTransaction transaction : views)
+ {
+ savepoints.add(transaction.getLastSavepoint());
+ }
+
+ return savepoints;
+ }
+ }
+
+ /**
+ * @author Simon McDuff
+ */
+ private final class CDOXATransactionStrategyImpl implements CDOTransactionStrategy
+ {
+ public CDOXATransactionStrategyImpl()
+ {
+ }
+
+ public void setTarget(InternalCDOTransaction transaction)
+ {
+ synchronized (views)
+ {
+ views.add(transaction);
+ }
+ }
+
+ public void unsetTarget(InternalCDOTransaction transaction)
+ {
+ synchronized (views)
+ {
+ views.remove(transaction);
+ }
+ }
+
+ private void check_access()
+ {
+ if (!allRequestEnabled)
+ {
+ throw new IllegalStateException("Commit from CDOTransaction is not allowed.");
+ }
+ }
+
+ public void commit(InternalCDOTransaction transactionCommit) throws Exception
+ {
+ check_access();
+ CDOXATransactionImpl.this.commit();
+ }
+
+ public void rollback(InternalCDOTransaction transaction, CDOSavepoint savepoint, boolean remote)
+ {
+ check_access();
+ CDOXATransactionImpl.this.rollback(savepoint, remote);
+ }
+
+ public CDOSavepoint setSavepoint(InternalCDOTransaction transaction)
+ {
+ check_access();
+ return CDOXATransactionImpl.this.setSavepoint();
+ }
+ }
+
+ /**
+ * @author Simon McDuff
+ */
+ public static abstract class CDOXAState
+ {
+ public static final CDOXAState DONE = new CDOXAState()
+ {
+ @Override
+ protected void handle(CDOXATransactionCommitContext xaTransaction) throws Exception
+ {
+ // Do nothing
+ }
+ };
+
+ protected void check_result(CommitTransactionResult result)
+ {
+ if (result != null && result.getRollbackMessage() != null)
+ {
+ throw new TransactionException(result.getRollbackMessage());
+ }
+ }
+
+ protected abstract void handle(CDOXATransactionCommitContext xaTransaction) throws Exception;
+ };
+
+ /**
+ * @author Simon McDuff
+ */
+ public static class CDOXAPhase1State extends CDOXAState
+ {
+ public static final CDOXAPhase1State INSTANCE = new CDOXAPhase1State();
+
+ @Override
+ protected void handle(CDOXATransactionCommitContext xaTransaction) throws Exception
+ {
+ xaTransaction.preCommit();
+
+ InternalCDOTransaction transaction = xaTransaction.getTransaction();
+ CDOSession session = xaTransaction.getTransaction().getSession();
+ IChannel channel = session.getChannel();
+ IFailOverStrategy failOverStrategy = session.getFailOverStrategy();
+
+ // Phase 1
+ {
+ CommitTransactionPhase1Request requestPhase1 = new CommitTransactionPhase1Request(channel, xaTransaction);
+ CommitTransactionResult result = failOverStrategy.send(requestPhase1, transaction.getCommitTimeout());
+ check_result(result);
+ xaTransaction.setResult(result);
+ xaTransaction.setState(CDOXAPhase2State.INSTANCE);
+ }
+ }
+ };
+
+ /**
+ * @author Simon McDuff
+ */
+ public static class CDOXAPhase2State extends CDOXAState
+ {
+ public static final CDOXAPhase2State INSTANCE = new CDOXAPhase2State();
+
+ public CDOXAPhase2State()
+ {
+ }
+
+ @Override
+ protected void handle(CDOXATransactionCommitContext xaTransaction) throws Exception
+ {
+ InternalCDOTransaction transaction = xaTransaction.getTransaction();
+ CDOSession session = xaTransaction.getTransaction().getSession();
+ IChannel channel = session.getChannel();
+ IFailOverStrategy failOverStrategy = session.getFailOverStrategy();
+
+ // Phase 2
+ {
+ CommitTransactionPhase2Request requestPhase2 = new CommitTransactionPhase2Request(channel, xaTransaction);
+ CommitTransactionResult result = failOverStrategy.send(requestPhase2, transaction.getCommitTimeout());
+ check_result(result);
+ xaTransaction.setState(CDOXAPhase3State.INSTANCE);
+ }
+ }
+ };
+
+ /**
+ * @author Simon McDuff
+ */
+ public static class CDOXAPhase3State extends CDOXAState
+ {
+ public static final CDOXAPhase3State INSTANCE = new CDOXAPhase3State();
+
+ public CDOXAPhase3State()
+ {
+ }
+
+ @Override
+ protected void handle(CDOXATransactionCommitContext xaTransaction) throws Exception
+ {
+ InternalCDOTransaction transaction = xaTransaction.getTransaction();
+ CDOSession session = xaTransaction.getTransaction().getSession();
+ IChannel channel = session.getChannel();
+ IFailOverStrategy failOverStrategy = session.getFailOverStrategy();
+
+ // Phase 2
+ {
+ CommitTransactionPhase3Request requestPhase3 = new CommitTransactionPhase3Request(channel, xaTransaction);
+ CommitTransactionResult result = failOverStrategy.send(requestPhase3, transaction.getCommitTimeout());
+ check_result(result);
+ xaTransaction.postCommit(xaTransaction.getResult());
+ xaTransaction.setState(null);
+ }
+ }
+ };
+
+ /**
+ * @author Simon McDuff
+ */
+ public static class CDOXACancel extends CDOXAState
+ {
+ public static final CDOXACancel INSTANCE = new CDOXACancel();
+
+ public CDOXACancel()
+ {
+ }
+
+ @Override
+ protected void handle(CDOXATransactionCommitContext xaTransaction) throws Exception
+ {
+ InternalCDOTransaction transaction = xaTransaction.getTransaction();
+ CDOSession session = xaTransaction.getTransaction().getSession();
+ IChannel channel = session.getChannel();
+ IFailOverStrategy failOverStrategy = session.getFailOverStrategy();
+
+ // Phase 2
+ {
+ CommitTransactionCancelRequest requestCancel = new CommitTransactionCancelRequest(channel, xaTransaction);
+ CommitTransactionResult result = failOverStrategy.send(requestCancel, transaction.getCommitTimeout());
+ check_result(result);
+ }
+ }
+ };
+
+ /**
+ * @author Simon McDuff
+ */
+ public static class CDOXAALLPhaseState extends CDOXAState
+ {
+ public static final CDOXAALLPhaseState INSTANCE = new CDOXAALLPhaseState();
+
+ public CDOXAALLPhaseState()
+ {
+ }
+
+ @Override
+ protected void handle(CDOXATransactionCommitContext xaTransaction) throws Exception
+ {
+ CDOTransactionStrategy.DEFAULT.commit(xaTransaction.getTransaction());
+ xaTransaction.setState(null);
+ }
+ }
+
+ /**
+ * @author Simon McDuff
+ */
+ public class CDOXAInternalAdapter implements Adapter
+ {
+ public CDOXATransactionImpl getCDOXA()
+ {
+ return CDOXATransactionImpl.this;
+ }
+
+ public Notifier getTarget()
+ {
+ return null;
+ }
+
+ public boolean isAdapterForType(Object type)
+ {
+ return false;
+ }
+
+ public void notifyChanged(Notification notification)
+ {
+ switch (notification.getEventType())
+ {
+ case Notification.ADD:
+ if (notification.getNewValue() instanceof InternalCDOTransaction)
+ {
+ CDOXATransactionImpl.this.add((InternalCDOTransaction)notification.getNewValue());
+ }
+ break;
+
+ case Notification.REMOVE:
+ if (notification.getOldValue() instanceof InternalCDOTransaction)
+ {
+ CDOXATransactionImpl.this.remove((InternalCDOTransaction)notification.getNewValue());
+ }
+ break;
+ }
+ }
+
+ public void setTarget(Notifier newTarget)
+ {
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/InternalCDOTransaction.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/InternalCDOTransaction.java
new file mode 100644
index 0000000000..3953aa94ad
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/InternalCDOTransaction.java
@@ -0,0 +1,33 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo;
+
+import org.eclipse.emf.cdo.CDOSavepoint;
+import org.eclipse.emf.cdo.CDOTransaction;
+import org.eclipse.emf.cdo.common.id.CDOIDProvider;
+
+/**
+ * @author Simon McDuff
+ * @since 2.0
+ */
+public interface InternalCDOTransaction extends CDOTransaction, CDOIDProvider
+{
+ public CDOCommitContext createCommitContext();
+
+ public void handleRollback(CDOSavepoint savepoint, boolean remote);
+
+ public CDOSavepoint handleSetSavepoint();
+
+ public CDOTransactionStrategy getTransactionStrategy();
+
+ public void setTransactionStrategy(CDOTransactionStrategy transactionStrategy);
+
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitNotificationIndication.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitNotificationIndication.java
index 8fe222ee0c..1d2ac87fbc 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitNotificationIndication.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitNotificationIndication.java
@@ -13,6 +13,7 @@ package org.eclipse.emf.internal.cdo.protocol;
import org.eclipse.emf.cdo.common.CDODataInput;
import org.eclipse.emf.cdo.common.CDOProtocolConstants;
+import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDAndVersion;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
@@ -86,6 +87,17 @@ public class CommitNotificationIndication extends CDOClientIndication
deltas.add(revisionDelta);
}
- session.handleCommitNotification(timeStamp, dirtyOIDs, deltas, null);
+ size = in.readInt();
+ if (PROTOCOL_TRACER.isEnabled())
+ {
+ PROTOCOL_TRACER.format("Reading {0} Detach Objects", size);
+ }
+ List<CDOID> detachedObjects = new ArrayList<CDOID>();
+ for (int i = 0; i < size; i++)
+ {
+ detachedObjects.add(in.readCDOID());
+ }
+
+ session.handleCommitNotification(timeStamp, dirtyOIDs, detachedObjects, deltas, null);
}
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionCancelRequest.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionCancelRequest.java
new file mode 100644
index 0000000000..45c146e670
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionCancelRequest.java
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo.protocol;
+
+import org.eclipse.emf.cdo.CDOTransaction;
+import org.eclipse.emf.cdo.common.CDODataInput;
+import org.eclipse.emf.cdo.common.CDODataOutput;
+import org.eclipse.emf.cdo.common.CDOProtocolConstants;
+
+import org.eclipse.emf.internal.cdo.CDOXATransactionCommitContext;
+
+import org.eclipse.net4j.channel.IChannel;
+
+import java.io.IOException;
+
+/**
+ * Determine at which moment the server side can complete the transaction.
+ * <p>
+ * At this stage, everything on the database was done except to flush on the disk.
+ * <p>
+ * It is useful to assure that all {@link CDOTransaction} involve in that commit are synchronize.
+ *
+ * @author Simon McDuff
+ */
+public class CommitTransactionCancelRequest extends CommitTransactionRequest
+{
+ public CommitTransactionCancelRequest(IChannel channel, CDOXATransactionCommitContext xaTransaction)
+ {
+ super(channel, xaTransaction);
+ }
+
+ @Override
+ protected short getSignalID()
+ {
+ return CDOProtocolConstants.SIGNAL_COMMIT_TRANSACTION_CANCEL;
+ }
+
+ @Override
+ protected void requesting(CDODataOutput out) throws IOException
+ {
+ requestingTransactionInfo(out);
+ }
+
+ @Override
+ protected CommitTransactionResult confirming(CDODataInput in) throws IOException
+ {
+ return confirmingCheckError(in);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionPhase1Request.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionPhase1Request.java
new file mode 100644
index 0000000000..d702e49e9b
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionPhase1Request.java
@@ -0,0 +1,64 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo.protocol;
+
+import org.eclipse.emf.cdo.CDOTransaction;
+import org.eclipse.emf.cdo.common.CDODataInput;
+import org.eclipse.emf.cdo.common.CDOProtocolConstants;
+import org.eclipse.emf.cdo.common.id.CDOIDProvider;
+
+import org.eclipse.emf.internal.cdo.CDOXATransactionCommitContext;
+
+import org.eclipse.net4j.channel.IChannel;
+
+import java.io.IOException;
+
+/**
+ * Phase 1 will send all the modifications to the server.
+ * <p>
+ * It needs to fill id mappings for objects immediately to be use by other {@link CDOTransaction} involve in that
+ * commit.
+ *
+ * @author Simon McDuff
+ */
+public class CommitTransactionPhase1Request extends CommitTransactionRequest
+{
+ public CommitTransactionPhase1Request(IChannel channel, final CDOXATransactionCommitContext xaTransaction)
+ {
+ super(channel, xaTransaction);
+ }
+
+ @Override
+ protected short getSignalID()
+ {
+ return CDOProtocolConstants.SIGNAL_COMMIT_TRANSACTION_PHASE1;
+ }
+
+ @Override
+ protected CommitTransactionResult confirming(CDODataInput in) throws IOException
+ {
+ CommitTransactionResult result = confirmingCheckError(in);
+ if (result != null)
+ {
+ return result;
+ }
+
+ result = confirmingTransactionResult(in);
+ confirmingIdMapping(in, result);
+ return result;
+ }
+
+ @Override
+ protected CDOIDProvider getIDProvider()
+ {
+ return (CDOIDProvider)commitContext;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionPhase2Request.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionPhase2Request.java
new file mode 100644
index 0000000000..8961395fc2
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionPhase2Request.java
@@ -0,0 +1,120 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo.protocol;
+
+import org.eclipse.emf.cdo.common.CDODataInput;
+import org.eclipse.emf.cdo.common.CDODataOutput;
+import org.eclipse.emf.cdo.common.CDOProtocolConstants;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.internal.common.id.CDOIDExternalTempImpl;
+import org.eclipse.emf.cdo.util.CDOURIUtil;
+
+import org.eclipse.emf.internal.cdo.CDOXATransactionCommitContext;
+import org.eclipse.emf.internal.cdo.InternalCDOTransaction;
+import org.eclipse.emf.internal.cdo.bundle.OM;
+
+import org.eclipse.net4j.channel.IChannel;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import org.eclipse.emf.common.util.URI;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * <p>
+ * Phase 2 consist of sending the mapping of temporary CDOID/final CDOID from other CDOTransaction.
+ * <p>
+ * It will return confirmation only when the commit is ready to flush to disk.
+ *
+ * @author Simon McDuff
+ */
+public class CommitTransactionPhase2Request extends CommitTransactionRequest
+{
+ private static final ContextTracer PROTOCOL = new ContextTracer(OM.DEBUG_PROTOCOL,
+ CommitTransactionPhase1Request.class);
+
+ public CommitTransactionPhase2Request(IChannel channel, final CDOXATransactionCommitContext xaTransaction)
+ {
+ super(channel, xaTransaction);
+ }
+
+ @Override
+ protected short getSignalID()
+ {
+ return CDOProtocolConstants.SIGNAL_COMMIT_TRANSACTION_PHASE2;
+ }
+
+ @Override
+ protected CDOXATransactionCommitContext getCommitContext()
+ {
+ return (CDOXATransactionCommitContext)super.getCommitContext();
+ }
+
+ @Override
+ protected void requesting(CDODataOutput out) throws IOException
+ {
+ requestingTransactionInfo(out);
+ requestingIdMapping(out);
+ }
+
+ @Override
+ protected CommitTransactionResult confirming(CDODataInput in) throws IOException
+ {
+ return confirmingCheckError(in);
+ }
+
+ /**
+ * Write ids that are needed. only If it needs to
+ */
+ protected void requestingIdMapping(CDODataOutput out) throws IOException
+ {
+ CDOXATransactionCommitContext context = getCommitContext();
+ Map<CDOIDExternalTempImpl, InternalCDOTransaction> requestedIDs = context.getRequestedIDs();
+ int size = requestedIDs.size();
+ out.writeInt(size);
+ if (PROTOCOL.isEnabled())
+ {
+ PROTOCOL.format("Number of ids requested: {0}", size);
+ }
+
+ for (Entry<CDOIDExternalTempImpl, InternalCDOTransaction> entry : requestedIDs.entrySet())
+ {
+ CDOIDExternalTempImpl tempID = entry.getKey();
+ URI oldURIExternal = URI.createURI(tempID.toURIFragment());
+ CDOID oldCDOID = CDOIDUtil.read(oldURIExternal.fragment(), null);
+
+ CDOXATransactionCommitContext commitContext = context.getTransactionManager().getCommitContext(entry.getValue());
+ if (commitContext == null)
+ {
+ throw new IllegalStateException("Missing informations. " + entry.getValue() + " isn't involved in the commit.");
+ }
+
+ CDOID newID = commitContext.getResult().getIDMappings().get(oldCDOID);
+ if (newID == null)
+ {
+ throw new IllegalStateException("Missing informations. " + oldCDOID.toURIFragment() + " isn't mapped in the commit.");
+ }
+
+ CDOID newIDExternal = CDOURIUtil.convertExternalCDOID(oldURIExternal, newID);
+ if (PROTOCOL.isEnabled())
+ {
+ PROTOCOL.format("ID mapping: {0} --> {1}", tempID.toURIFragment(), newIDExternal.toURIFragment());
+ }
+ out.writeCDOID(tempID);
+ out.writeCDOID(newIDExternal);
+
+ context.getResult().addIDMapping(tempID, newIDExternal);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionPhase3Request.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionPhase3Request.java
new file mode 100644
index 0000000000..3e1e7dfec6
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionPhase3Request.java
@@ -0,0 +1,65 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo.protocol;
+
+import org.eclipse.emf.cdo.CDOTransaction;
+import org.eclipse.emf.cdo.common.CDODataInput;
+import org.eclipse.emf.cdo.common.CDODataOutput;
+import org.eclipse.emf.cdo.common.CDOProtocolConstants;
+
+import org.eclipse.emf.internal.cdo.CDOXATransactionCommitContext;
+
+import org.eclipse.net4j.channel.IChannel;
+
+import java.io.IOException;
+
+/**
+ * Determine at which moment the server side can complete the transaction.
+ * <p>
+ * At this stage, everything on the database was done except to flush on the disk.
+ * <p>
+ * It is useful to assure that all {@link CDOTransaction} involve in that commit are synchronize.
+ *
+ * @author Simon McDuff
+ */
+public class CommitTransactionPhase3Request extends CommitTransactionRequest
+{
+ public CommitTransactionPhase3Request(IChannel channel, final CDOXATransactionCommitContext xaTransaction)
+ {
+ super(channel, xaTransaction);
+ }
+
+ @Override
+ protected short getSignalID()
+ {
+ return CDOProtocolConstants.SIGNAL_COMMIT_TRANSACTION_PHASE3;
+ }
+
+ @Override
+ protected void requesting(CDODataOutput out) throws IOException
+ {
+ requestingTransactionInfo(out);
+ }
+
+ @Override
+ protected CommitTransactionResult confirming(CDODataInput in) throws IOException
+ {
+ CommitTransactionResult result = confirmingCheckError(in);
+ if (result != null)
+ {
+ return result;
+ }
+
+ CDOXATransactionCommitContext context = (CDOXATransactionCommitContext)getCommitContext();
+ confirmingNewPackage(in, context.getResult());
+ return context.getResult();
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionRequest.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionRequest.java
index 01045cc5d7..d544014d83 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionRequest.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionRequest.java
@@ -9,6 +9,7 @@
* Eike Stepper - initial API and implementation
* Simon McDuff - http://bugs.eclipse.org/201266
* Simon McDuff - http://bugs.eclipse.org/215688
+ * Simon McDuff - http://bugs.eclipse.org/213402
**************************************************************************/
package org.eclipse.emf.internal.cdo.protocol;
@@ -27,8 +28,8 @@ import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.spi.common.InternalCDOPackage;
import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
+import org.eclipse.emf.internal.cdo.CDOCommitContext;
import org.eclipse.emf.internal.cdo.CDOSessionImpl;
-import org.eclipse.emf.internal.cdo.CDOTransactionImpl;
import org.eclipse.emf.internal.cdo.bundle.OM;
import org.eclipse.emf.internal.cdo.util.RevisionAdjuster;
@@ -49,12 +50,12 @@ public class CommitTransactionRequest extends CDOClientRequest<CommitTransaction
private static final ContextTracer PROTOCOL_TRACER = new ContextTracer(OM.DEBUG_PROTOCOL,
CommitTransactionRequest.class);
- private CDOTransactionImpl transaction;
+ protected CDOCommitContext commitContext;
- public CommitTransactionRequest(IChannel channel, final CDOTransactionImpl transaction)
+ public CommitTransactionRequest(IChannel channel, CDOCommitContext commitContext)
{
super(channel);
- this.transaction = transaction;
+ this.commitContext = commitContext;
}
@Override
@@ -63,24 +64,55 @@ public class CommitTransactionRequest extends CDOClientRequest<CommitTransaction
return CDOProtocolConstants.SIGNAL_COMMIT_TRANSACTION;
}
+ protected CDOCommitContext getCommitContext()
+ {
+ return commitContext;
+ }
+
@Override
protected CDOIDProvider getIDProvider()
{
- return transaction;
+ return commitContext.getTransaction();
}
@Override
protected void requesting(CDODataOutput out) throws IOException
{
- List<CDOPackage> newPackages = transaction.getNewPackages();
- Collection<CDOResource> newResources = transaction.getNewResources().values();
- Collection<CDOObject> newObjects = transaction.getNewObjects().values();
- Collection<CDORevisionDelta> revisionDeltas = transaction.getRevisionDeltas().values();
+ requestingTransactionInfo(out);
+ requestingCommit(out);
+ }
+
+ @Override
+ protected CommitTransactionResult confirming(CDODataInput in) throws IOException
+ {
+ CommitTransactionResult result = confirmingCheckError(in);
+ if (result != null)
+ {
+ return result;
+ }
+ result = confirmingTransactionResult(in);
+ confirmingNewPackage(in, result);
+ confirmingIdMapping(in, result);
+ return result;
+ }
+
+ protected void requestingTransactionInfo(CDODataOutput out) throws IOException
+ {
+ out.writeInt(commitContext.getTransaction().getViewID());
+ }
+
+ protected void requestingCommit(CDODataOutput out) throws IOException
+ {
+ List<CDOPackage> newPackages = commitContext.getNewPackages();
+ Collection<CDOResource> newResources = commitContext.getNewResources().values();
+ Collection<CDOObject> newObjects = commitContext.getNewObjects().values();
+ Collection<CDORevisionDelta> revisionDeltas = commitContext.getRevisionDeltas().values();
+ Collection<CDOID> detachedObjects = commitContext.getDetachedObjects();
- out.writeInt(transaction.getViewID());
out.writeInt(newPackages.size());
out.writeInt(newResources.size() + newObjects.size());
out.writeInt(revisionDeltas.size());
+ out.writeInt(detachedObjects.size());
if (PROTOCOL_TRACER.isEnabled())
{
@@ -110,8 +142,8 @@ public class CommitTransactionRequest extends CDOClientRequest<CommitTransaction
PROTOCOL_TRACER.format("Writing {0} dirty objects", revisionDeltas.size());
}
- Map<CDOID, CDOObject> dirtyObjects = transaction.getDirtyObjects();
- RevisionAdjuster revisionAdjuster = new RevisionAdjuster(transaction);
+ Map<CDOID, CDOObject> dirtyObjects = commitContext.getDirtyObjects();
+ RevisionAdjuster revisionAdjuster = new RevisionAdjuster(getIDProvider());
for (CDORevisionDelta revisionDelta : revisionDeltas)
{
out.writeCDORevisionDelta(revisionDelta);
@@ -119,10 +151,15 @@ public class CommitTransactionRequest extends CDOClientRequest<CommitTransaction
InternalCDORevision revision = (InternalCDORevision)object.cdoRevision();
revisionAdjuster.adjustRevision(revision, revisionDelta);
}
+
+ for (CDOID id : detachedObjects)
+ {
+ out.writeCDOID(id);
+ }
+
}
- @Override
- protected CommitTransactionResult confirming(CDODataInput in) throws IOException
+ protected CommitTransactionResult confirmingCheckError(CDODataInput in) throws IOException
{
boolean success = in.readBoolean();
if (!success)
@@ -131,12 +168,20 @@ public class CommitTransactionRequest extends CDOClientRequest<CommitTransaction
OM.LOG.error(rollbackMessage);
return new CommitTransactionResult(rollbackMessage);
}
+ return null;
+ }
+ protected CommitTransactionResult confirmingTransactionResult(CDODataInput in) throws IOException
+ {
long timeStamp = in.readLong();
CommitTransactionResult result = new CommitTransactionResult(timeStamp);
+ return result;
+ }
- CDOSessionImpl session = transaction.getSession();
- List<CDOPackage> newPackages = transaction.getNewPackages();
+ protected void confirmingNewPackage(CDODataInput in, CommitTransactionResult result) throws IOException
+ {
+ CDOSessionImpl session = (CDOSessionImpl)commitContext.getTransaction().getSession();
+ List<CDOPackage> newPackages = commitContext.getNewPackages();
for (CDOPackage newPackage : newPackages)
{
if (newPackage.getParentURI() == null)
@@ -153,7 +198,13 @@ public class CommitTransactionRequest extends CDOClientRequest<CommitTransaction
}
}
}
+ }
+ /*
+ * Write ids that are needed
+ */
+ public void confirmingIdMapping(CDODataInput in, CommitTransactionResult result) throws IOException
+ {
for (;;)
{
CDOIDTemp oldID = (CDOIDTemp)in.readCDOID();
@@ -165,20 +216,6 @@ public class CommitTransactionRequest extends CDOClientRequest<CommitTransaction
CDOID newID = in.readCDOID();
result.addIDMapping(oldID, newID);
}
-
- return result;
- }
-
- @SuppressWarnings("unused")
- private void writeDirtyObjects(CDODataOutput out) throws IOException
- {
- Collection<CDOObject> dirtyObjects = transaction.getDirtyObjects().values();
- if (PROTOCOL_TRACER.isEnabled())
- {
- PROTOCOL_TRACER.format("Writing {0} dirty objects", dirtyObjects.size());
- }
-
- writeRevisions(out, dirtyObjects);
}
private void writeRevisions(CDODataOutput out, Collection<?> objects) throws IOException
@@ -190,4 +227,5 @@ public class CommitTransactionRequest extends CDOClientRequest<CommitTransaction
out.writeCDORevision(revision, CDORevision.UNCHUNKED);
}
}
+
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CDOViewSetPackageRegistryImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CDOViewSetPackageRegistryImpl.java
new file mode 100644
index 0000000000..cc9042384a
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CDOViewSetPackageRegistryImpl.java
@@ -0,0 +1,83 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ **************************************************************************/
+package org.eclipse.emf.internal.cdo.util;
+
+import org.eclipse.emf.cdo.CDOView;
+import org.eclipse.emf.cdo.CDOViewSet;
+
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.impl.EPackageRegistryImpl;
+
+/**
+ * @author Simon McDuff
+ */
+public class CDOViewSetPackageRegistryImpl extends EPackageRegistryImpl
+{
+ private static final long serialVersionUID = 1L;
+
+ private CDOViewSet viewSet;
+
+ public CDOViewSetPackageRegistryImpl(CDOViewSet viewSet)
+ {
+ this.viewSet = viewSet;
+ }
+
+ @Override
+ public synchronized EPackage getEPackage(String nsURI)
+ {
+ EPackage ePackage = super.getEPackage(nsURI);
+ if (ePackage == null)
+ {
+ for (CDOView view : viewSet.getViews())
+ {
+ ePackage = view.getSession().getPackageRegistry().getEPackage(nsURI);
+ if (ePackage != null)
+ {
+ break;
+ }
+ }
+ }
+
+ return ePackage;
+ }
+
+ @Override
+ public Object put(String key, Object value)
+ {
+ super.put(key, value);
+
+ for (CDOView view : viewSet.getViews())
+ {
+ view.getSession().getPackageRegistry().put(key, value);
+ }
+
+ return null;
+ }
+
+ @Override
+ synchronized public Object get(Object key)
+ {
+ Object ePackage = super.get(key);
+ if (ePackage == null)
+ {
+ for (CDOView view : viewSet.getViews())
+ {
+ ePackage = view.getSession().getPackageRegistry().get(key);
+ if (ePackage != null)
+ {
+ return ePackage;
+ }
+ }
+ }
+
+ return ePackage;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/FSMUtil.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/FSMUtil.java
index 91a6778b62..b55a0a6215 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/FSMUtil.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/FSMUtil.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Eike Stepper - initial API and implementation
+ * Simon McDuff - http://bugs.eclipse.org/246705
**************************************************************************/
package org.eclipse.emf.internal.cdo.util;
@@ -28,7 +29,9 @@ import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EGenericType;
import org.eclipse.emf.ecore.EModelElement;
+import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import java.lang.reflect.Method;
@@ -92,6 +95,12 @@ public final class FSMUtil
return state == CDOState.TRANSIENT || state == CDOState.PREPARED;
}
+ public static boolean isNew(CDOObject object)
+ {
+ CDOState state = object.cdoState();
+ return state == CDOState.NEW;
+ }
+
/**
* @param view
* Only needed if object is a meta instance.
@@ -157,9 +166,51 @@ public final class FSMUtil
return null;
}
- public static Iterator<InternalCDOObject> iterator(Collection<?> instances, final CDOViewImpl view)
+ /**
+ * Similar to {@link EcoreUtil#getAllProperContents(Resource, boolean)} except gives only one depth
+ */
+ public static Iterator<InternalCDOObject> getProperContents(final InternalCDOObject object)
+ {
+ final boolean isResource = object instanceof Resource;
+ final CDOView cdoView = object.cdoView();
+ final Iterator<EObject> delegate = object.eContents().iterator();
+
+ return new Iterator<InternalCDOObject>()
+ {
+ private Object next;
+
+ public boolean hasNext()
+ {
+ while (delegate.hasNext())
+ {
+ InternalEObject eObject = (InternalEObject)delegate.next();
+
+ if (isResource || eObject.eDirectResource() == null)
+ {
+ next = adapt(eObject, cdoView);
+ if (next instanceof InternalCDOObject)
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public InternalCDOObject next()
+ {
+ return (InternalCDOObject)next;
+ }
+
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ public static Iterator<InternalCDOObject> iterator(final Iterator<?> delegate, final CDOViewImpl view)
{
- final Iterator<?> delegate = instances.iterator();
return new Iterator<InternalCDOObject>()
{
private Object next;
@@ -189,4 +240,9 @@ public final class FSMUtil
}
};
}
+
+ public static Iterator<InternalCDOObject> iterator(Collection<?> instances, final CDOViewImpl view)
+ {
+ return iterator(instances.iterator(), view);
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/RevisionAdjuster.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/RevisionAdjuster.java
index 48eb6b7b7c..705c343130 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/RevisionAdjuster.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/RevisionAdjuster.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Simon McDuff - initial API and implementation
+ * Simon McDuff - http://bugs.eclipse.org/246705
**************************************************************************/
package org.eclipse.emf.internal.cdo.util;
@@ -15,6 +16,7 @@ import org.eclipse.emf.cdo.common.id.CDOIDProvider;
import org.eclipse.emf.cdo.common.model.CDOFeature;
import org.eclipse.emf.cdo.common.revision.CDOReferenceProxy;
import org.eclipse.emf.cdo.common.revision.delta.CDOAddFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOContainerFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta;
@@ -45,6 +47,13 @@ public class RevisionAdjuster extends CDOFeatureDeltaVisitorImpl
}
@Override
+ public void visit(CDOContainerFeatureDelta delta)
+ {
+ // Delta value must have been adjusted before!
+ revision.setContainerID(idProvider.provideCDOID(revision.getContainerID()));
+ }
+
+ @Override
public void visit(CDOAddFeatureDelta delta)
{
// Delta value must have been adjusted before!

Back to the top