Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon McDuff2009-09-24 23:59:13 +0000
committerSimon McDuff2009-09-24 23:59:13 +0000
commit6205cfdc4d446f58ce68367a88f909447ac3119f (patch)
treee321ce8f3ce548ac8a49f0d74303776aec18c850
parent9d7dc8460cd53f7e1bf31ae52ce05d3031f68de6 (diff)
downloadcdo-6205cfdc4d446f58ce68367a88f909447ac3119f.tar.gz
cdo-6205cfdc4d446f58ce68367a88f909447ac3119f.tar.xz
cdo-6205cfdc4d446f58ce68367a88f909447ac3119f.zip
[279982] ObjectNotFoundException when calling the set method.
https://bugs.eclipse.org/bugs/show_bug.cgi?id=279982
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsAllConfigs.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_279982_Test.java207
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOUtil.java41
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ObjectNotFoundException.java13
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOStaleObject.java21
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOStaleReferencePolicy.java110
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java23
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStore.java36
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/messages/messages.properties2
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java35
10 files changed, 481 insertions, 9 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsAllConfigs.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsAllConfigs.java
index 28e578c7e6..b321f529d6 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsAllConfigs.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsAllConfigs.java
@@ -53,6 +53,7 @@ import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_273758_Test;
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_276696_Test;
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_278900_Test;
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_279565_Test;
+import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_279982_Test;
import org.eclipse.emf.cdo.tests.config.impl.ConfigTest;
import org.eclipse.emf.cdo.tests.config.impl.ConfigTestSuite;
@@ -156,6 +157,7 @@ public abstract class AllTestsAllConfigs extends ConfigTestSuite
testClasses.add(Bugzilla_276696_Test.class);
testClasses.add(Bugzilla_278900_Test.class);
testClasses.add(Bugzilla_279565_Test.class);
+ testClasses.add(Bugzilla_279982_Test.class);
// TODO testClasses.add(NonCDOResourceTest.class);
// TODO testClasses.add(GeneratedEcoreTest.class);
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_279982_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_279982_Test.java
new file mode 100644
index 0000000000..d3715d7047
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_279982_Test.java
@@ -0,0 +1,207 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ */
+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.model4.GenRefMultiNonContained;
+import org.eclipse.emf.cdo.tests.model4.GenRefSingleContained;
+import org.eclipse.emf.cdo.tests.model4.GenRefSingleNonContained;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.cdo.util.ObjectNotFoundException;
+import org.eclipse.emf.cdo.view.CDOStaleReferencePolicy;
+
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * Deadlock in CDOView
+ * <p>
+ * See https://bugs.eclipse.org/279982
+ *
+ * @author Simon McDuff
+ */
+public class Bugzilla_279982_Test extends AbstractCDOTest
+{
+ public void testBugzilla_279982_Single() throws Exception
+ {
+ CDOSession session = openModel1Session();
+ CDOTransaction tx = session.openTransaction();
+ CDOResource res = tx.getOrCreateResource("/resource1");
+ tx.options().setStaleReferenceBehaviour(CDOStaleReferencePolicy.PROXY);
+ GenRefSingleContained container = getModel4Factory().createGenRefSingleContained();
+ GenRefSingleNonContained reference = getModel4Factory().createGenRefSingleNonContained();
+ GenRefSingleNonContained contained = getModel4Factory().createGenRefSingleNonContained();
+ container.setElement(contained);
+ reference.setElement(contained);
+ res.getContents().add(container);
+ res.getContents().add(reference);
+ tx.commit();
+ container.setElement(null);
+ tx.commit();
+
+ assertNull(container.getElement());
+ EObject element = reference.getElement();
+ assertNotNull(element);
+
+ try
+ {
+ assertTrue(CDOUtil.isStaleObject(element));
+ element.eContainer();
+ fail("Should fail");
+ }
+ catch (ObjectNotFoundException ex)
+ {
+ // ignore
+ }
+ catch (Exception ex)
+ {
+ fail("Should have an ObjectNotFoundException");
+ }
+
+ tx.options().setStaleReferenceBehaviour(CDOStaleReferencePolicy.EXCEPTION);
+
+ try
+ {
+ reference.getElement();
+ fail("Should fail");
+ }
+ catch (ObjectNotFoundException ex)
+ {
+ // ignore
+ }
+ catch (Exception ex)
+ {
+ fail("Should have an ObjectNotFoundException");
+ }
+
+ CDOUtil.cleanStaleReference(reference, getModel4Package().getGenRefSingleNonContained_Element());
+ assertNull(reference.getElement());
+ tx.commit();
+
+ clearCache(session.getRevisionManager());
+
+ // Verification that the commit is good
+ tx = session.openTransaction();
+ res = tx.getOrCreateResource("/resource1");
+ reference = (GenRefSingleNonContained)res.getContents().get(1);
+ assertNull(reference.getElement());
+ }
+
+ public void testBugzilla_279982_Multi() throws Exception
+ {
+ CDOSession session = openModel1Session();
+ CDOTransaction tx = session.openTransaction();
+ CDOResource res = tx.getOrCreateResource("/resource1");
+ tx.options().setStaleReferenceBehaviour(CDOStaleReferencePolicy.PROXY);
+ GenRefSingleContained container = getModel4Factory().createGenRefSingleContained();
+ GenRefMultiNonContained reference = getModel4Factory().createGenRefMultiNonContained();
+ GenRefSingleNonContained contained = getModel4Factory().createGenRefSingleNonContained();
+ container.setElement(contained);
+ reference.getElements().add(contained);
+ res.getContents().add(container);
+ res.getContents().add(reference);
+ tx.commit();
+ container.setElement(null);
+ tx.commit();
+
+ assertNull(container.getElement());
+ assertNotNull(reference.getElements().get(0));
+
+ tx.options().setStaleReferenceBehaviour(CDOStaleReferencePolicy.EXCEPTION);
+
+ try
+ {
+ reference.getElements().get(0);
+ fail("Should fail");
+ }
+ catch (ObjectNotFoundException ex)
+ {
+ // ignore
+ }
+ catch (Exception ex)
+ {
+ fail("Should have an ObjectNotFoundException");
+ }
+
+ CDOUtil.cleanStaleReference(reference, getModel4Package().getGenRefMultiNonContained_Elements(), 0);
+ assertEquals(0, reference.getElements().size());
+ tx.commit();
+
+ clearCache(session.getRevisionManager());
+
+ // Verification that the commit is good
+ tx = session.openTransaction();
+ res = tx.getOrCreateResource("/resource1");
+ reference = (GenRefMultiNonContained)res.getContents().get(1);
+ assertEquals(0, reference.getElements().size());
+ }
+
+ public void testBugzilla_279982_Multi_RevisionPrefetchingPolicy() throws Exception
+ {
+ CDOSession session = openModel1Session();
+ {
+ CDOTransaction tx = session.openTransaction();
+ CDOResource res = tx.getOrCreateResource("/resource1");
+ // tx.options().setUnresolveableObjectToNullEnabled(true);
+ GenRefSingleContained container = getModel4Factory().createGenRefSingleContained();
+ GenRefMultiNonContained reference = getModel4Factory().createGenRefMultiNonContained();
+ GenRefSingleNonContained contained = getModel4Factory().createGenRefSingleNonContained();
+ GenRefSingleNonContained contained2 = getModel4Factory().createGenRefSingleNonContained();
+ container.setElement(contained);
+ reference.getElements().add(contained);
+ reference.getElements().add(contained2);
+ res.getContents().add(container);
+ res.getContents().add(reference);
+ res.getContents().add(contained2);
+ tx.commit();
+ res.getContents().remove(contained2);
+ tx.commit();
+ }
+
+ clearCache(session.getRevisionManager());
+
+ CDOTransaction tx = session.openTransaction();
+ CDOResource res = tx.getOrCreateResource("/resource1");
+
+ tx.options().setRevisionPrefetchingPolicy(CDOUtil.createRevisionPrefetchingPolicy(100));
+ GenRefMultiNonContained reference = (GenRefMultiNonContained)res.getContents().get(1);
+
+ assertNotNull(reference.getElements().get(0));
+
+ try
+ {
+ assertNotNull(reference.getElements().get(1));
+ fail("Should fail");
+ }
+ catch (ObjectNotFoundException ex)
+ {
+ // ignore
+ }
+ catch (Exception ex)
+ {
+ fail("Should have an ObjectNotFoundException");
+ }
+
+ CDOUtil.cleanStaleReference(reference, getModel4Package().getGenRefMultiNonContained_Elements(), 0);
+ assertEquals(1, reference.getElements().size());
+ tx.commit();
+
+ clearCache(session.getRevisionManager());
+
+ // Verification that the commit is good
+ tx = session.openTransaction();
+ res = tx.getOrCreateResource("/resource1");
+ reference = (GenRefMultiNonContained)res.getContents().get(1);
+ assertEquals(1, reference.getElements().size());
+ }
+}
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 f72f2188e4..2c04b6d992 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
@@ -21,6 +21,7 @@ import org.eclipse.emf.cdo.session.remote.CDORemoteSessionManager;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.transaction.CDOXATransaction;
import org.eclipse.emf.cdo.view.CDORevisionPrefetchingPolicy;
+import org.eclipse.emf.cdo.view.CDOStaleObject;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.cdo.view.CDOViewSet;
@@ -41,6 +42,7 @@ import org.eclipse.emf.ecore.EGenericType;
import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.EStringToStringMapEntryImpl;
import org.eclipse.emf.ecore.resource.Resource;
@@ -197,6 +199,45 @@ public final class CDOUtil
}
/**
+ * @since 3.0
+ */
+ public static boolean isStaleObject(Object object)
+ {
+ return object instanceof CDOStaleObject;
+ }
+
+ /**
+ * @since 3.0
+ */
+ public static void cleanStaleReference(EObject eObject, EStructuralFeature eFeature)
+ {
+ if (!eFeature.isMany() && eFeature.getEContainingClass() != null)
+ {
+ InternalCDOObject cdoObject = (InternalCDOObject)getCDOObject(eObject);
+ cdoObject.eStore().unset(cdoObject, eFeature);
+ }
+ }
+
+ /**
+ * @since 3.0
+ */
+ public static void cleanStaleReference(EObject eObject, EStructuralFeature eFeature, int index)
+ {
+ if (eFeature.isMany() && eFeature.getEContainingClass() != null)
+ {
+ InternalCDOObject cdoObject = (InternalCDOObject)getCDOObject(eObject);
+ try
+ {
+ cdoObject.eStore().remove(cdoObject, eFeature, index);
+ }
+ catch (ObjectNotFoundException ex)
+ {
+ // Ignore the exception
+ }
+ }
+ }
+
+ /**
* @since 2.0
*/
public static void load(EObject eObject, CDOView view)
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ObjectNotFoundException.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ObjectNotFoundException.java
index 2d03b269ab..b763a15cfd 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ObjectNotFoundException.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/ObjectNotFoundException.java
@@ -4,7 +4,7 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* Simon McDuff - initial API and implementation
* Eike Stepper - maintenance
@@ -28,8 +28,19 @@ public class ObjectNotFoundException extends CDOException
{
private static final long serialVersionUID = 1L;
+ private final CDOID id;
+
public ObjectNotFoundException(CDOID id)
{
super(MessageFormat.format(Messages.getString("ObjectNotFoundException.0"), id, id.isTemporary())); //$NON-NLS-1$
+ this.id = id;
+ }
+
+ /**
+ * @since 3.0
+ */
+ public CDOID getID()
+ {
+ return id;
}
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOStaleObject.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOStaleObject.java
new file mode 100644
index 0000000000..1b4a1c5bb5
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOStaleObject.java
@@ -0,0 +1,21 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ */
+package org.eclipse.emf.cdo.view;
+
+/**
+ * A marker interface for stale objects as produced by {@link CDOStaleReferencePolicy#PROXY}.
+ *
+ * @author Simon McDuff
+ * @since 3.0
+ */
+public interface CDOStaleObject
+{
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOStaleReferencePolicy.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOStaleReferencePolicy.java
new file mode 100644
index 0000000000..42d500a0f0
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOStaleReferencePolicy.java
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2004 - 2009 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ */
+package org.eclipse.emf.cdo.view;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.cdo.util.ObjectNotFoundException;
+
+import org.eclipse.emf.internal.cdo.messages.Messages;
+
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/**
+ * Specifies a policy on how to deal with stale references.
+ *
+ * @author Simon McDuff
+ * @since 3.0
+ */
+public interface CDOStaleReferencePolicy
+{
+ /**
+ * A default stale reference policy. It will throw an exception each time.
+ */
+ public static final CDOStaleReferencePolicy EXCEPTION = new CDOStaleReferencePolicy()
+ {
+ public Object processStaleReference(EObject source, EStructuralFeature feature, int index, CDOID target)
+ {
+ throw new ObjectNotFoundException(target);
+ }
+
+ @Override
+ public String toString()
+ {
+ return Messages.getString("CDOStaleReferencePolicy.0");
+ }
+ };
+
+ /**
+ * Returns a proxy object with the appropriate EClass. The proxy object supports the {@link InternalEObject#eClass()
+ * eClass()} and {@link InternalEObject#eIsProxy() eIsProxy()} methods. For all invocations to other methods the proxy
+ * object throws an {@link ObjectNotFoundException}. The receiver can use {@link CDOUtil#isStaleObject(Object)} to
+ * detect proxy objects.
+ */
+ public static final CDOStaleReferencePolicy PROXY = new CDOStaleReferencePolicy()
+ {
+ public Object processStaleReference(EObject source, final EStructuralFeature feature, int index, final CDOID target)
+ {
+ final EClassifier type = feature.getEType();
+ InvocationHandler handler = new InvocationHandler()
+ {
+ public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable
+ {
+ if (arg1.getName().equals("eIsProxy"))
+ {
+ return false;
+ }
+
+ if (arg1.getName().equals("eClass"))
+ {
+ return type;
+ }
+
+ throw new ObjectNotFoundException(target);
+ }
+ };
+
+ Class<?> instanceClass = type.getInstanceClass();
+ Class<?>[] interfaces = null;
+
+ // Be sure to have only interface
+ if (instanceClass.isInterface())
+ {
+ interfaces = new Class<?>[] { instanceClass, InternalEObject.class, CDOStaleObject.class };
+ }
+ else
+ {
+ interfaces = new Class<?>[] { InternalEObject.class, CDOStaleObject.class };
+ }
+ return Proxy.newProxyInstance(instanceClass.getClassLoader(), interfaces, handler);
+ }
+
+ @Override
+ public String toString()
+ {
+ return Messages.getString("CDOStaleReferencePolicy.1");
+ }
+ };
+
+ /**
+ * Returns an object that we want to return to the caller (clients). Exception thrown will be received by the caller
+ * (clients).
+ */
+ public Object processStaleReference(EObject source, EStructuralFeature feature, int index, CDOID target);
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java
index ec47767936..25d895226c 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java
@@ -400,7 +400,21 @@ public interface CDOView extends CDOCommonView, INotifier, IOptionsContainer
public void setStrongReferencePolicy(CDOAdapterPolicy policy);
/**
- * Returns the CDORevisionPrefetchingPolicy in used.
+ * Returns the CDOStaleReferencePolicy in use.
+ *
+ * @since 3.0
+ */
+ public CDOStaleReferencePolicy getStaleReferenceBehaviour();
+
+ /**
+ * Sets a policy on how to deal with stale references.
+ *
+ * @since 3.0
+ */
+ public void setStaleReferenceBehaviour(CDOStaleReferencePolicy policy);
+
+ /**
+ * Returns the CDORevisionPrefetchingPolicy in use.
*/
public CDORevisionPrefetchingPolicy getRevisionPrefetchingPolicy();
@@ -425,6 +439,13 @@ public interface CDOView extends CDOCommonView, INotifier, IOptionsContainer
{
}
+ /**
+ * @since 3.0
+ */
+ public interface StaleReferencePolicyEvent extends IOptionsEvent
+ {
+ }
+
public interface ChangeSubscriptionPoliciesEvent extends IOptionsEvent
{
}
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 9bec62a58d..41c1fbf104 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
@@ -31,6 +31,7 @@ import org.eclipse.emf.cdo.internal.common.revision.delta.CDOSetFeatureDeltaImpl
import org.eclipse.emf.cdo.internal.common.revision.delta.CDOUnsetFeatureDeltaImpl;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
+import org.eclipse.emf.cdo.util.ObjectNotFoundException;
import org.eclipse.emf.cdo.view.CDORevisionPrefetchingPolicy;
import org.eclipse.emf.internal.cdo.bundle.OM;
@@ -43,6 +44,7 @@ import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.InternalEObject.EStore;
import org.eclipse.emf.ecore.impl.EStoreEObjectImpl;
@@ -127,7 +129,8 @@ public final class CDOStore implements EStore
}
InternalCDORevision revision = getRevisionForReading(cdoObject);
- return (InternalEObject)cdoObject.cdoView().convertIDToObject(revision.getContainerID());
+ return (InternalEObject)convertIdToObject(cdoObject.cdoView(), cdoObject, EcorePackage.eINSTANCE
+ .eContainingFeature(), -1, revision.getContainerID());
}
public int getContainingFeatureID(InternalEObject eObject)
@@ -154,7 +157,8 @@ public final class CDOStore implements EStore
}
InternalCDORevision revision = getRevisionForReading(cdoObject);
- return (InternalEObject)cdoObject.cdoView().convertIDToObject(revision.getResourceID());
+ return (InternalEObject)convertIdToObject(cdoObject.cdoView(), cdoObject, EcorePackage.eINSTANCE
+ .eContainingFeature(), -1, revision.getResourceID());
}
@Deprecated
@@ -294,7 +298,7 @@ public final class CDOStore implements EStore
for (int i = 0; i < result.length; i++)
{
result[i] = resolveProxy(revision, feature, i, result[i]);
- result[i] = cdoObject.cdoView().convertIDToObject(result[i]);
+ result[i] = convertIdToObject(cdoObject.cdoView(), eObject, feature, i, result[i]);
}
}
@@ -380,16 +384,14 @@ public final class CDOStore implements EStore
// TODO Clarify feature maps
if (feature instanceof EReference)
{
- // The EReference condition should be in the CDOType.convertToCDO. Since common package do not have access to
- // InternalCDOView I kept it here.
- value = view.convertIDToObject(value);
+ value = convertIdToObject(view, eObject, feature, index, value);
}
else if (FeatureMapUtil.isFeatureMap(feature))
{
FeatureMap.Entry entry = (FeatureMap.Entry)value;
EStructuralFeature innerFeature = entry.getEStructuralFeature();
Object innerValue = entry.getValue();
- Object convertedValue = view.convertIDToObject(innerValue);
+ Object convertedValue = convertIdToObject(view, eObject, feature, index, innerValue);
if (convertedValue != innerValue)
{
value = FeatureMapUtil.createEntry(innerFeature, convertedValue);
@@ -408,6 +410,26 @@ public final class CDOStore implements EStore
return value;
}
+ private Object convertIdToObject(InternalCDOView view, EObject eObject, EStructuralFeature feature, int index,
+ Object value)
+ {
+ // The EReference condition should be in the CDOType.convertToCDO. Since common package do not have access to
+ // InternalCDOView I kept it here.
+ try
+ {
+ value = view.convertIDToObject(value);
+ }
+ catch (ObjectNotFoundException ex)
+ {
+ if (value instanceof CDOID)
+ {
+ value = view.options().getStaleReferenceBehaviour().processStaleReference(eObject, feature, index, ex.getID());
+ }
+ }
+
+ return value;
+ }
+
/**
* @since 3.0
*/
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/messages/messages.properties b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/messages/messages.properties
index 5dc3512bc7..f6f81aa3c9 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/messages/messages.properties
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/messages/messages.properties
@@ -24,6 +24,8 @@ CDOSessionFactory.1=Query is empty: {0}
CDOSessionImpl.0=Generated packages locally not available: {0}
CDOSessionImpl.1=Commit notification arrived while session is inactive
CDOSessionImpl.2=Commit notification arrived while session is inactive
+CDOStaleReferencePolicy.0=EXCEPTION
+CDOStaleReferencePolicy.1=PROXY
CDOTransactionImpl.0=Not a ResourceFolder: {0}
CDOTransactionImpl.1=Root resource node {0} does not exist
CDOTransactionImpl.10=Duplicate ID: {0}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
index 8ab0657e37..9051c2dafb 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
@@ -44,6 +44,7 @@ import org.eclipse.emf.cdo.view.CDOAdapterPolicy;
import org.eclipse.emf.cdo.view.CDOFeatureAnalyzer;
import org.eclipse.emf.cdo.view.CDOQuery;
import org.eclipse.emf.cdo.view.CDORevisionPrefetchingPolicy;
+import org.eclipse.emf.cdo.view.CDOStaleReferencePolicy;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.cdo.view.CDOViewEvent;
import org.eclipse.emf.cdo.view.CDOViewInvalidationEvent;
@@ -1971,6 +1972,8 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView
private CDORevisionPrefetchingPolicy revisionPrefetchingPolicy;
+ private CDOStaleReferencePolicy staleReferencePolicy = CDOStaleReferencePolicy.EXCEPTION;
+
private HashBag<CDOAdapterPolicy> changeSubscriptionPolicies = new HashBag<CDOAdapterPolicy>();
private CDOAdapterPolicy adapterReferencePolicy = CDOAdapterPolicy.ALL;
@@ -2093,6 +2096,25 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView
}
}
+ public CDOStaleReferencePolicy getStaleReferenceBehaviour()
+ {
+ return staleReferencePolicy;
+ }
+
+ public void setStaleReferenceBehaviour(CDOStaleReferencePolicy policy)
+ {
+ if (policy == null)
+ {
+ policy = CDOStaleReferencePolicy.EXCEPTION;
+ }
+
+ if (staleReferencePolicy != policy)
+ {
+ staleReferencePolicy = policy;
+ fireEvent(new StaleReferencePolicyEventImpl());
+ }
+ }
+
public ReferenceType getCacheReferenceType()
{
if (objects instanceof ReferenceValueMap.Strong<?, ?>)
@@ -2247,5 +2269,18 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView
super(OptionsImpl.this);
}
}
+
+ /**
+ * @author Simon McDuff
+ */
+ private final class StaleReferencePolicyEventImpl extends OptionsEvent implements StaleReferencePolicyEvent
+ {
+ private static final long serialVersionUID = 1L;
+
+ public StaleReferencePolicyEventImpl()
+ {
+ super(OptionsImpl.this);
+ }
+ }
}
}

Back to the top