[352204] [Legacy] Failing event PREPARE in state CLEAN : state machine
issue with legacy mode
https://bugs.eclipse.org/bugs/show_bug.cgi?id=352204
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java
index 8e60a12..88b06ea 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java
@@ -247,5 +247,6 @@
     testClasses.add(Bugzilla_359669_Test.class);
     testClasses.add(Bugzilla_359992_Test.class);
     testClasses.add(Bugzilla_363287_Test.class);
+    testClasses.add(Bugzilla_352204_Test.class);
   }
 }
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_352204_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_352204_Test.java
new file mode 100644
index 0000000..06ee55a
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_352204_Test.java
@@ -0,0 +1,127 @@
+/**

+ * Copyright (c) 2004 - 2011 Eike Stepper (Berlin, Germany) and others.

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ * 

+ * Contributors:

+ *    Eike Stepper - initial API and implementation

+ */

+package org.eclipse.emf.cdo.tests.bugzilla;

+

+import org.eclipse.emf.cdo.eresource.CDOResource;

+import org.eclipse.emf.cdo.session.CDOSession;

+import org.eclipse.emf.cdo.tests.AbstractCDOTest;

+import org.eclipse.emf.cdo.tests.model6.A;

+import org.eclipse.emf.cdo.tests.model6.D;

+import org.eclipse.emf.cdo.transaction.CDOPushTransaction;

+import org.eclipse.emf.cdo.transaction.CDOTransaction;

+import org.eclipse.emf.cdo.view.CDOView;

+

+import org.eclipse.emf.ecore.EObject;

+

+import org.eclipse.gmf.runtime.notation.Diagram;

+import org.eclipse.gmf.runtime.notation.MeasurementUnit;

+import org.eclipse.gmf.runtime.notation.Node;

+import org.eclipse.gmf.runtime.notation.NotationFactory;

+

+import java.io.File;

+import java.io.IOException;

+

+/**

+ * @author Martin Fluegge

+ */

+public class Bugzilla_352204_Test extends AbstractCDOTest

+{

+  private static final String MODEL_LOCATION_PATH = "myResource";

+

+  public void testChangesImportWithNewLegacyElementsWithCustomFileAndReconstructSavePoints() throws Exception

+  {

+    importWithNewLegacyElements(true);

+  }

+

+  public void _testChangesImportWithNewLegacyElementsWithCustomFileAndNotReconstructSavePoints() throws Exception

+  {

+    importWithNewLegacyElements(false);

+  }

+

+  private void importWithNewLegacyElements(boolean reconstructSavePoints) throws Exception

+  {

+    // Step 1 : create model

+    CDOSession session = openSession();

+    CDOTransaction transaction = session.openTransaction();

+

+    CDOResource resource = transaction.createResource(getResourcePath(MODEL_LOCATION_PATH));

+    resource.getContents().add(createModel());

+    transaction.commit();

+    session.close();

+

+    // Step 2 : open a push transaction a save locally a modification

+    // Step 2.1 : open a push transaction

+    File fileForStoringChanges = createTempFile();

+    CDOPushTransaction pushTransaction = createPushTransaction(fileForStoringChanges, reconstructSavePoints);

+

+    // Step 2.2 : create a new element

+    addNewChildren(pushTransaction);

+

+    // Step 2.3 : save locally

+    pushTransaction.commit();

+    pushTransaction.getSession().close();

+

+    // Step 3 : load changes

+    pushTransaction = createPushTransaction(fileForStoringChanges, reconstructSavePoints);

+

+    pushTransaction.getSession().close();

+  }

+

+  private CDOPushTransaction createPushTransaction(File fileForStoringChanges, boolean reconstructSavePoints)

+      throws IOException

+  {

+    CDOSession session = openSession();

+    CDOTransaction delegate = session.openTransaction();

+    if (fileForStoringChanges == null)

+    {

+      return new CDOPushTransaction(delegate);

+    }

+

+    return new CDOPushTransaction(delegate, fileForStoringChanges, reconstructSavePoints);

+  }

+

+  private Diagram getDiagram(CDOView view)

+  {

+    CDOResource resource = view.getResource(getResourcePath(MODEL_LOCATION_PATH));

+    A a = (A)resource.getContents().get(0);

+    D d = a.getOwnedDs().get(0);

+    return (Diagram)d.getData();

+  }

+

+  /**

+   * Creates the test model.

+   */

+  private EObject createModel()

+  {

+    A a = getModel6Factory().createA();

+    D d = getModel6Factory().createD();

+

+    Diagram diagram = NotationFactory.eINSTANCE.createDiagram();

+    diagram.setMeasurementUnit(MeasurementUnit.PIXEL_LITERAL);

+

+    d.setData(diagram);

+    a.getOwnedDs().add(d);

+

+    return a;

+  }

+

+  @SuppressWarnings("unchecked")

+  private void addNewChildren(CDOTransaction transaction)

+  {

+    Diagram diagram = getDiagram(transaction);

+    A a = (A)diagram.eContainer().eContainer();

+    diagram.setElement(a);

+

+    Node child2 = NotationFactory.eINSTANCE.createNode();

+    child2.setType("type");

+    diagram.getPersistedChildren().add(child2);

+  }

+}

diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_359966_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_359966_Test.java
index ced755e..153f690 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_359966_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_359966_Test.java
@@ -63,12 +63,12 @@
     checkDiagramAsCorrectlyBeenModified(transaction);

   }

 

-  public void _testChangesImportWithNewLegacyElementsWithCustomFileAndReconstructSavePoints() throws Exception

+  public void testChangesImportWithNewLegacyElementsWithCustomFileAndReconstructSavePoints() throws Exception

   {

     importWithNewLegacyElements(true);

   }

 

-  public void _testChangesImportWithNewLegacyElementsWithCustomFileAndNotReconstructSavePoints() throws Exception

+  public void testChangesImportWithNewLegacyElementsWithCustomFileAndNotReconstructSavePoints() throws Exception

   {

     importWithNewLegacyElements(false);

   }

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 9ce6023..3d8e63c 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
@@ -1291,6 +1291,12 @@
     if (!FSMUtil.isTransient(this))
     {
       InternalCDOObject cdoObject = FSMUtil.adapt(object, cdoView());
+
+      if (CDOUtil.isLegacyObject(cdoObject) && cdoObject.cdoState() == CDOState.CLEAN)
+      {
+        return;
+      }
+
       attached(cdoObject, cdoView().toTransaction());
     }
   }
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java
index 1d16571..5d6cdd2 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java
@@ -384,6 +384,7 @@
       registerWrapper(this);
       counter.increment();
       view.registerObject(this);
+
       revisionToInstanceContainer();
 
       for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(revision.getEClass()))
@@ -422,8 +423,13 @@
   protected void revisionToInstanceContainer()
   {
     Object containerID = revision.getContainerID();
+    EObject oldContainer = instance.eContainer();
     InternalEObject container = getEObjectFromPotentialID(view, null, containerID);
-    setInstanceContainer(container, revision.getContainingFeatureID());
+
+    if (oldContainer != container)
+    {
+      setInstanceContainer(container, revision.getContainingFeatureID());
+    }
   }
 
   /**
@@ -541,7 +547,27 @@
         {
           if (object != CDORevisionData.NIL)
           {
-            instance.eSet(feature, object);
+            EReference reference = (EReference)feature;
+            if (reference.isContainment())
+            {
+              if (object != null)
+              {
+                // Calling eSet it not the optimal approach, but currently there is no other way to set the value here.
+                // To avoid attaching already processed (clean) objects a check was introduced to
+                // CDOResourceImpl.attached(EObject).
+                // If we find a way to avoid the call of eSet and if we are able to only set the feature value directly
+                // this check can be removed from CDOResourceImpl. See also Bug 352204.
+                instance.eSet(feature, object);
+              }
+              else
+              {
+                instance.eSet(feature, null);
+              }
+            }
+            else
+            {
+              instance.eSet(feature, object);
+            }
           }
           else
           {