diff options
author | Eike Stepper | 2009-08-12 07:39:10 +0000 |
---|---|---|
committer | Eike Stepper | 2009-08-12 07:39:10 +0000 |
commit | 9e2e222f328c0204054a8fec8ea8293e1957552d (patch) | |
tree | f7ef405f97b9b4ee408e59d2a8843229769b011c | |
parent | ea0651691e2abdf45c54b0c43037d05e5198db81 (diff) | |
download | cdo-committers/estepper/redesign-dangling.tar.gz cdo-committers/estepper/redesign-dangling.tar.xz cdo-committers/estepper/redesign-dangling.zip |
[283945] Prevent EObjects from being passed to a repositorycommitters/estepper/redesign-dangling
https://bugs.eclipse.org/bugs/show_bug.cgi?id=283945
16 files changed, 241 insertions, 271 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempObjectExternalImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempObjectExternalImpl.java index ddb691719d..dcbbd94c4c 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempObjectExternalImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempObjectExternalImpl.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 @@ -30,4 +30,10 @@ public class CDOIDTempObjectExternalImpl extends CDOIDExternalImpl implements CD { return Type.EXTERNAL_TEMP_OBJECT; } + + @Override + public boolean isTemporary() + { + return true; + } } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreChunkReader.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreChunkReader.java index 9449d8726f..04ac422b6c 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreChunkReader.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreChunkReader.java @@ -4,7 +4,7 @@ * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * + * * Contributors: * Eike Stepper - initial API and implementation * Stefan Winkler - Bug 283998: [DB] Chunk reading for multiple chunks fails @@ -60,6 +60,7 @@ public class DBStoreChunkReader extends StoreChunkReader implements IDBStoreChun { builder.append(" OR "); //$NON-NLS-1$ } + builder.append(CDODBSchema.LIST_IDX); builder.append("="); //$NON-NLS-1$ builder.append(index); diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java index a3105e2526..adf9339a57 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/embedded/EmbeddedClientSessionProtocol.java @@ -492,7 +492,6 @@ public class EmbeddedClientSessionProtocol extends Lifecycle implements CDOSessi CDORemoteSession remoteSession = manager.createRemoteSession(session.getSessionID(), session.getUserID(), session.isSubscribed()); result.add(remoteSession); - } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOAutoAttacher.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOAutoAttacher.java index c27b1accea..1ef6c31c14 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOAutoAttacher.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOAutoAttacher.java @@ -11,6 +11,7 @@ */ package org.eclipse.emf.cdo.transaction; +import org.eclipse.emf.cdo.CDOIDDangling; import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.common.revision.delta.CDOAddFeatureDelta; import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta; @@ -88,6 +89,11 @@ public class CDOAutoAttacher extends CDODefaultTransactionHandler res.eResource().getContents().add(cdoObject); } } + else if (object instanceof CDOIDDangling) + { + CDOIDDangling cdoIDDangling = (CDOIDDangling)object; + res.eResource().getContents().add(cdoIDDangling.getTarget()); + } } private void check(EObject referrer, EReference reference, EObject element) diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOIDDanglingImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOIDDanglingImpl.java index ddd8f03866..7b0b4dce88 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOIDDanglingImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOIDDanglingImpl.java @@ -35,8 +35,6 @@ public class CDOIDDanglingImpl extends AbstractCDOID implements CDOIDDangling private InternalEObject target; - // private List<Reference> references = new ArrayList<Reference>(); - public CDOIDDanglingImpl(InternalEObject target) { CheckUtil.checkArg(target, "target"); @@ -48,33 +46,6 @@ public class CDOIDDanglingImpl extends AbstractCDOID implements CDOIDDangling return target; } - // public List<Reference> getReferences() - // { - // return references; - // } - // - // public void addReference(InternalCDOObject sourceObject, EStructuralFeature sourceFeature) - // { - // synchronized (references) - // { - // for (Reference reference : references) - // { - // if (reference.getSourceObject() == sourceObject && reference.getSourceFeature() == sourceFeature) - // { - // return; - // } - // } - // - // references.add(new ReferenceImpl(sourceObject, sourceFeature)); - // } - // } - // - // public void dispose() - // { - // target = null; - // references.clear(); - // } - public Type getType() { return Type.DANGLING_OBJECT; @@ -167,35 +138,4 @@ public class CDOIDDanglingImpl extends AbstractCDOID implements CDOIDDangling { return toURIFragment().compareTo(((CDOIDDanglingImpl)o).toURIFragment()); } - - // /** - // * @author Eike Stepper - // */ - // public final class ReferenceImpl implements Reference - // { - // private InternalCDOObject sourceObject; - // - // private EStructuralFeature sourceFeature; - // - // public ReferenceImpl(InternalCDOObject sourceObject, EStructuralFeature sourceFeature) - // { - // this.sourceObject = sourceObject; - // this.sourceFeature = sourceFeature; - // } - // - // public InternalCDOObject getSourceObject() - // { - // return sourceObject; - // } - // - // public EStructuralFeature getSourceFeature() - // { - // return sourceFeature; - // } - // - // public CDOIDDangling getTargetID() - // { - // return CDOIDDanglingImpl.this; - // } - // } } 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 9f71d5d6c9..df9bbe46be 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 @@ -306,7 +306,7 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec } InternalCDOView view = cdoView(); - revision.setContainerID(eContainer == null ? CDOID.NULL : (CDOID)cdoView().convertObjectToID(eContainer, true)); + revision.setContainerID(eContainer == null ? CDOID.NULL : (CDOID)cdoView().convertObjectToID(eContainer)); revision.setContainingFeatureID(eContainerFeatureID); Resource directResource = eDirectResource(); @@ -1005,7 +1005,7 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec } EStructuralFeature.Internal internalFeature = (EStructuralFeature.Internal)eFeature; - EReference oppositeReference = instance.cdoID().isTemporary() ? null : internalFeature.getEOpposite(); + EReference oppositeReference = internalFeature.getEOpposite(); CDOStore cdoStore = instance.cdoView().getStore(); EStore eStore = instance.eStore(); 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 97bef7dde8..7cedd9a063 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 @@ -200,7 +200,7 @@ public final class CDOStore implements EStore // TODO Clarify feature maps if (feature instanceof EReference) { - value = cdoObject.cdoView().convertObjectToID(value, true); + value = cdoObject.cdoView().convertObjectToID(value); } InternalCDORevision revision = getRevisionForReading(cdoObject); @@ -218,7 +218,7 @@ public final class CDOStore implements EStore // TODO Clarify feature maps if (feature instanceof EReference) { - value = cdoObject.cdoView().convertObjectToID(value, true); + value = cdoObject.cdoView().convertObjectToID(value); } InternalCDORevision revision = getRevisionForReading(cdoObject); @@ -236,7 +236,7 @@ public final class CDOStore implements EStore // TODO Clarify feature maps if (feature instanceof EReference) { - value = cdoObject.cdoView().convertObjectToID(value, true); + value = cdoObject.cdoView().convertObjectToID(value); } InternalCDORevision revision = getRevisionForReading(cdoObject); @@ -315,7 +315,7 @@ public final class CDOStore implements EStore { Object oldValue = revision.basicGet(feature, index); oldValue = resolveProxy(revision, feature, index, oldValue); - value = cdoObject.cdoView().convertObjectToID(value, true); + value = cdoObject.cdoView().convertObjectToID(value); } Object oldValue = revision.basicSet(feature, index, value); @@ -336,7 +336,7 @@ public final class CDOStore implements EStore } CDOID newContainerID = newEContainer == null ? CDOID.NULL : (CDOID)cdoObject.cdoView().convertObjectToID( - newEContainer, true); + newEContainer); CDOID newResourceID = newResource == null ? CDOID.NULL : newResource.cdoID(); CDOFeatureDelta delta = new CDOContainerFeatureDeltaImpl(newResourceID, newContainerID, newContainerFeatureID); @@ -511,7 +511,7 @@ public final class CDOStore implements EStore { // The EReference condition should be in the CDOType.convertToCDO. Since common package do not have access to // InternalCDOView I kept it here. - value = view.convertObjectToID(value, true); + value = view.convertObjectToID(value); } else if (FeatureMapUtil.isFeatureMap(feature)) { diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSavepointImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSavepointImpl.java index 2beb6cca4b..ea2fff4fa4 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSavepointImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSavepointImpl.java @@ -12,10 +12,8 @@ */ package org.eclipse.emf.internal.cdo.transaction; -import org.eclipse.emf.cdo.CDOIDDangling; import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.common.id.CDOID; -import org.eclipse.emf.cdo.common.revision.CDOReferenceAdjustable; import org.eclipse.emf.cdo.common.revision.CDOReferenceAdjuster; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta; @@ -30,6 +28,7 @@ import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta; import org.eclipse.net4j.util.collection.MultiMap; import org.eclipse.emf.spi.cdo.InternalCDOTransaction; +import org.eclipse.emf.spi.cdo.InternalCDOTransaction.InternalCDOCommitContext; import java.util.Collection; import java.util.Collections; @@ -45,7 +44,7 @@ import java.util.concurrent.ConcurrentMap; * @author Simon McDuff * @since 2.0 */ -public class CDOSavepointImpl extends AbstractSavepoint implements CDOReferenceAdjustable +public class CDOSavepointImpl extends AbstractSavepoint { private Map<CDOID, CDOResource> newResources = new HashMap<CDOID, CDOResource>(); @@ -359,40 +358,15 @@ public class CDOSavepointImpl extends AbstractSavepoint implements CDOReferenceA getUserTransaction().rollback(this); } - public void applyReferenceAdjuster(CDOReferenceAdjuster referenceAdjuster) + public static void applyReferenceAdjuster(InternalCDOCommitContext context, CDOReferenceAdjuster referenceAdjuster) { - adjustObjects(referenceAdjuster, newResources.values()); - adjustObjects(referenceAdjuster, newObjects.values()); - adjustObjects(referenceAdjuster, dirtyObjects.values()); - adjustRevisionDeltas(referenceAdjuster, revisionDeltas.values()); + adjustObjects(referenceAdjuster, context.getNewResources().values()); + adjustObjects(referenceAdjuster, context.getNewObjects().values()); + adjustObjects(referenceAdjuster, context.getDirtyObjects().values()); + adjustRevisionDeltas(referenceAdjuster, context.getRevisionDeltas().values()); } - // TTT - public void checkNotDanglig() - { - checkNotDanglig(newResources.keySet()); - checkNotDanglig(newObjects.keySet()); - checkNotDanglig(dirtyObjects.keySet()); - checkNotDanglig(revisionDeltas.keySet()); - - checkNotDanglig(baseNewObjects.keySet()); - checkNotDanglig(detachedObjects.keySet()); - checkNotDanglig(sharedDetachedObjects); - } - - // TTT - private void checkNotDanglig(Collection<CDOID> ids) - { - for (CDOID id : ids) - { - if (id instanceof CDOIDDangling) - { - throw new IllegalArgumentException("DANGLING ID: " + ((CDOIDDangling)id).getTarget()); - } - } - } - - private static void adjustObjects(CDOReferenceAdjuster referenceAdjuster, Collection<? extends CDOObject> objects) + public static void adjustObjects(CDOReferenceAdjuster referenceAdjuster, Collection<? extends CDOObject> objects) { for (CDOObject object : objects) { @@ -401,7 +375,7 @@ public class CDOSavepointImpl extends AbstractSavepoint implements CDOReferenceA } } - private static void adjustRevisionDeltas(CDOReferenceAdjuster referenceAdjuster, + public static void adjustRevisionDeltas(CDOReferenceAdjuster referenceAdjuster, Collection<? extends CDORevisionDelta> deltas) { for (CDORevisionDelta delta : deltas) diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSingleTransactionStrategyImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSingleTransactionStrategyImpl.java index 924b49aa19..766162e511 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSingleTransactionStrategyImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSingleTransactionStrategyImpl.java @@ -4,12 +4,14 @@ * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * + * * Contributors: * Simon McDuff - initial API and implementation **************************************************************************/ package org.eclipse.emf.internal.cdo.transaction; +import org.eclipse.emf.cdo.common.revision.CDOReferenceAdjuster; +import org.eclipse.emf.cdo.spi.common.revision.CDOIDMapper; import org.eclipse.emf.cdo.transaction.CDOSavepoint; import org.eclipse.emf.internal.cdo.bundle.OM; @@ -49,24 +51,38 @@ public class CDOSingleTransactionStrategyImpl implements CDOTransactionStrategy TRACER.format("CDOCommitContext.preCommit"); //$NON-NLS-1$ } - commitContext.preCommit(); + CDOIDMapper idMapper = new CDOIDMapper(); + CDOReferenceAdjuster referenceAdjuster = commitContext.createAdjuster(idMapper); + CDOSavepointImpl.applyReferenceAdjuster(commitContext, referenceAdjuster); CommitTransactionResult result = null; - if (commitContext.getTransaction().isDirty()) + + try { - OMMonitor monitor = new EclipseMonitor(progressMonitor); - result = transaction.getSession().getSessionProtocol().commitTransaction(commitContext, monitor); + commitContext.preCommit(); - String rollbackMessage = result.getRollbackMessage(); - if (rollbackMessage != null) + if (commitContext.getTransaction().isDirty()) { - throw new TransactionException(rollbackMessage); + OMMonitor monitor = new EclipseMonitor(progressMonitor); + result = transaction.getSession().getSessionProtocol().commitTransaction(commitContext, monitor); + + String rollbackMessage = result.getRollbackMessage(); + if (rollbackMessage != null) + { + throw new TransactionException(rollbackMessage); + } } - } - if (TRACER.isEnabled()) + if (TRACER.isEnabled()) + { + TRACER.format("CDOCommitContext.postCommit"); //$NON-NLS-1$ + } + } + catch (Exception ex) { - TRACER.format("CDOCommitContext.postCommit"); //$NON-NLS-1$ + idMapper.reverseIDMappings(); + CDOSavepointImpl.applyReferenceAdjuster(commitContext, idMapper); + throw ex; } commitContext.postCommit(result); diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java index 005a700448..93e178f5a3 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java @@ -17,8 +17,6 @@ import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.CDOState; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDAndVersion; -import org.eclipse.emf.cdo.common.id.CDOIDExternal; -import org.eclipse.emf.cdo.common.id.CDOIDObject; import org.eclipse.emf.cdo.common.id.CDOIDTemp; import org.eclipse.emf.cdo.common.id.CDOIDUtil; import org.eclipse.emf.cdo.common.model.CDOModelUtil; @@ -48,6 +46,7 @@ import org.eclipse.emf.cdo.transaction.CDOTransactionFinishedEvent; import org.eclipse.emf.cdo.transaction.CDOTransactionHandler; import org.eclipse.emf.cdo.transaction.CDOTransactionStartedEvent; import org.eclipse.emf.cdo.util.CDOURIUtil; +import org.eclipse.emf.cdo.util.CDOUtil; import org.eclipse.emf.cdo.util.DanglingReferenceException; import org.eclipse.emf.cdo.util.ResourceNotFoundException; import org.eclipse.emf.cdo.view.CDOViewResourcesEvent; @@ -559,9 +558,9 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa } @Override - public Object convertObjectToID(Object potentialObject, boolean onlyPersistedID) + public Object convertObjectToID(Object potentialObject) { - potentialObject = super.convertObjectToID(potentialObject, onlyPersistedID); + potentialObject = super.convertObjectToID(potentialObject); if (potentialObject instanceof InternalEObject) { InternalEObject target = (InternalEObject)potentialObject; @@ -639,122 +638,20 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa progressMonitor = new NullProgressMonitor(); } - CDOIDMapper idMapper = null; - try { - idMapper = adjustDanglingReferences(); getTransactionStrategy().commit(this, progressMonitor); } catch (TransactionException ex) { - undoIDMappings(idMapper); throw ex; } catch (Exception ex) { - undoIDMappings(idMapper); throw new TransactionException(ex); } } - private CDOIDMapper adjustDanglingReferences() - { - final CDOIDMapper idMapper = new CDOIDMapper(); - final Map<CDOID, CDOObject> detachedObjects = getDetachedObjects(); - CDOReferenceAdjuster danglingReferenceAdjuster = new CDOReferenceAdjuster() - { - public CDOID adjustReference(CDOID id) - { - if (id instanceof CDOIDObject) - { - CDOIDObject objectID = (CDOIDObject)id; - CDOObject target = detachedObjects.get(objectID); - if (target != null) - { - // Is it external now? - if (target.eResource() != null) - { - CDOIDExternal newID = CDOIDUtil.createExternal(EcoreUtil.getURI(target).toString()); - idMapper.putIDMapping(objectID, newID); - return newID; - } - - throw new DanglingReferenceException(target); - } - } - else if (id instanceof CDOIDDangling) - { - CDOIDDangling danglingID = (CDOIDDangling)id; - - // Was it already mapped? - CDOID newID = idMapper.getIDMapping(danglingID); - if (newID != null) - { - return newID; - } - - // Was it attached in the meantime? - EObject target = danglingID.getTarget(); - if (target instanceof InternalCDOObject) // TODO Legacy? - { - InternalCDOObject cdoObject = (InternalCDOObject)target; - if (cdoObject.cdoView() == CDOTransactionImpl.this) - { - newID = cdoObject.cdoID(); - idMapper.putIDMapping(danglingID, newID); - return newID; - } - } - - // Is it external? - if (target.eResource() != null) - { - newID = CDOIDUtil.createExternal(EcoreUtil.getURI(target).toString()); - idMapper.putIDMapping(danglingID, newID); - return newID; - } - - throw new DanglingReferenceException(target); - } - - return id; - } - }; - - applyReferenceAdjuster(danglingReferenceAdjuster); - checkNotDanglig(); - return idMapper; - } - - private void undoIDMappings(CDOIDMapper idMapper) - { - if (idMapper != null) - { - idMapper.reverseIDMappings(); - applyReferenceAdjuster(idMapper); - } - } - - // TTT - public void checkNotDanglig() - { - for (CDOSavepointImpl itrSavepoint = lastSavepoint; itrSavepoint != null; itrSavepoint = itrSavepoint - .getPreviousSavepoint()) - { - itrSavepoint.checkNotDanglig(); - } - } - - public void applyReferenceAdjuster(CDOReferenceAdjuster referenceAdjuster) - { - for (CDOSavepointImpl itrSavepoint = lastSavepoint; itrSavepoint != null; itrSavepoint = itrSavepoint - .getPreviousSavepoint()) - { - itrSavepoint.applyReferenceAdjuster(referenceAdjuster); - } - } - public void commit() throws TransactionException { commit(null); @@ -1371,6 +1268,8 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa private List<CDOPackageUnit> newPackageUnits; + private CDOIDMapper mapper = new CDOIDMapper(); + public CDOCommitContextImpl() { CDOTransactionImpl transaction = getTransaction(); @@ -1417,6 +1316,11 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa return revisionDeltas; } + public CDOIDMapper getCDOIDMapper() + { + return mapper; + } + public void preCommit() { if (isDirty()) @@ -1448,6 +1352,69 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa } } + public CDOReferenceAdjuster createAdjuster(final CDOIDMapper idMapper) + { + CDOReferenceAdjuster danglingReferenceAdjuster = new CDOReferenceAdjuster() + { + public CDOID adjustReference(CDOID id) + { + if (id instanceof CDOIDDangling) + { + CDOIDDangling danglingID = (CDOIDDangling)id; + + // Was it already mapped? + CDOID newID = idMapper.getIDMapping(danglingID); + if (newID != null) + { + return newID; + } + + // Was it attached in the meantime? + EObject target = danglingID.getTarget(); + InternalCDOObject cdoObject = (InternalCDOObject)CDOUtil.getCDOObject(target); + if (cdoObject != null) // TODO Legacy? + { + if (cdoObject.cdoView() == CDOTransactionImpl.this) + { + newID = cdoObject.cdoID(); + idMapper.putIDMapping(danglingID, newID); + return newID; + } + else if (!FSMUtil.isTransient(cdoObject)) + { + // Object belong to another repository + if (!FSMUtil.isNew(cdoObject)) + { + // Create an external reference + newID = CDOIDUtil.createExternal(EcoreUtil.getURI(target).toString()); + idMapper.putIDMapping(danglingID, newID); + return newID; + } + + // If it belong to another Repository and it is a new objects.... probably need to be in a XATransaction + // or commit the other transaction before. + throw new DanglingReferenceException(target); + } + } + + // Not from CDO Repository but external + if (target.eResource() != null) + { + newID = CDOIDUtil.createExternal(EcoreUtil.getURI(target).toString()); + idMapper.putIDMapping(danglingID, newID); + return newID; + } + + throw new DanglingReferenceException(target); + } + + return id; + } + }; + + return danglingReferenceAdjuster; + } + public void postCommit(CommitTransactionResult result) { if (isDirty()) @@ -1528,6 +1495,12 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa } } + public void commitFail() + { + getCDOIDMapper().reverseIDMappings(); + CDOSavepointImpl.applyReferenceAdjuster(this, getCDOIDMapper()); + } + @SuppressWarnings("unchecked") private void preCommit(Map objects) { diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOXACommitContextImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOXACommitContextImpl.java index b7d50015a3..b5718a1899 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOXACommitContextImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOXACommitContextImpl.java @@ -10,6 +10,7 @@ **************************************************************************/ package org.eclipse.emf.internal.cdo.transaction; +import org.eclipse.emf.cdo.CDOIDDangling; import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.model.CDOPackageUnit; @@ -17,12 +18,13 @@ import org.eclipse.emf.cdo.common.revision.CDOReferenceAdjuster; import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta; import org.eclipse.emf.cdo.eresource.CDOResource; import org.eclipse.emf.cdo.internal.common.id.CDOIDTempObjectExternalImpl; +import org.eclipse.emf.cdo.spi.common.revision.CDOIDMapper; import org.eclipse.emf.cdo.util.CDOUtil; -import org.eclipse.emf.internal.cdo.messages.Messages; import org.eclipse.emf.internal.cdo.transaction.CDOXATransactionImpl.CDOXAState; +import org.eclipse.emf.internal.cdo.util.FSMUtil; -import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.spi.cdo.InternalCDOObject; import org.eclipse.emf.spi.cdo.InternalCDOTransaction; import org.eclipse.emf.spi.cdo.CDOSessionProtocol.CommitTransactionResult; @@ -31,7 +33,6 @@ import org.eclipse.emf.spi.cdo.InternalCDOXATransaction.InternalCDOXACommitConte import org.eclipse.core.runtime.IProgressMonitor; -import java.text.MessageFormat; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -56,6 +57,8 @@ public class CDOXACommitContextImpl implements InternalCDOXACommitContext private Map<InternalCDOObject, CDOIDTempObjectExternalImpl> objectToID = new HashMap<InternalCDOObject, CDOIDTempObjectExternalImpl>(); + private CDOIDMapper idMapper; + public CDOXACommitContextImpl(CDOXATransactionImpl manager, InternalCDOCommitContext commitContext) { transactionManager = manager; @@ -138,33 +141,9 @@ public class CDOXACommitContextImpl implements InternalCDOXACommitContext return true; } - @Deprecated - public CDOID provideCDOID(Object idOrObject) + public CDOIDMapper getCDOIDMapper() { - // TODO Check / remove this method!!! - CDOID id = (CDOID)idOrObject; - if (id instanceof CDOIDTempObjectExternalImpl) - { - if (idOrObject instanceof InternalEObject) - { - CDOIDTempObjectExternalImpl proxyTemp = (CDOIDTempObjectExternalImpl)id; - if (!requestedIDs.containsKey(proxyTemp)) - { - InternalCDOObject cdoObject = (InternalCDOObject)CDOUtil.getCDOObject((InternalEObject)idOrObject); - InternalCDOTransaction cdoTransaction = (InternalCDOTransaction)cdoObject.cdoView(); - getTransactionManager().add(cdoTransaction, proxyTemp); - requestedIDs.put(proxyTemp, cdoTransaction); - objectToID.put(cdoObject, proxyTemp); - } - } - else - { - throw new IllegalArgumentException(MessageFormat.format( - Messages.getString("CDOXACommitContextImpl.0"), idOrObject)); //$NON-NLS-1$ - } - } - - return id; + return idMapper; } public void preCommit() @@ -194,4 +173,52 @@ public class CDOXACommitContextImpl implements InternalCDOXACommitContext delegateCommitContext.postCommit(result); } + + public void commitFail() + { + getCDOIDMapper().reverseIDMappings(); + CDOSavepointImpl.applyReferenceAdjuster(this, getCDOIDMapper()); + } + + public CDOReferenceAdjuster createAdjuster(CDOIDMapper idMapper) + { + this.idMapper = idMapper; + final CDOReferenceAdjuster delegateAjuster = delegateCommitContext.createAdjuster(idMapper); + CDOReferenceAdjuster adjuster = new CDOReferenceAdjuster() + { + public CDOID adjustReference(CDOID id) + { + if (id instanceof CDOIDDangling) + { + CDOIDDangling danglingID = (CDOIDDangling)id; + EObject target = danglingID.getTarget(); + InternalCDOObject cdoObject = (InternalCDOObject)CDOUtil.getCDOObject(target); + + if (!FSMUtil.isTransient(cdoObject) && cdoObject.cdoView() != delegateCommitContext.getTransaction()) + { + // Only register objects from others CDO repository that are persisted + if (target.eResource() != null) + { + InternalCDOTransaction transaction = (InternalCDOTransaction)cdoObject.cdoView(); + CDOIDTempObjectExternalImpl idExternalTemp = getTransactionManager().getCDOIDExternalTemp(target); + getTransactionManager().add(transaction, idExternalTemp); + requestedIDs.put(idExternalTemp, transaction); + objectToID.put(cdoObject, idExternalTemp); + getCDOIDMapper().putIDMapping(danglingID, idExternalTemp); + id = idExternalTemp; + } + } + } + + return delegateAjuster.adjustReference(id); + } + }; + + return adjuster; + } + + public void adjustReferences(CDOReferenceAdjuster adjuster) + { + CDOSavepointImpl.applyReferenceAdjuster(this, adjuster); + } }; diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOXATransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOXATransactionImpl.java index c4279d09ee..d6085277c0 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOXATransactionImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOXATransactionImpl.java @@ -12,6 +12,10 @@ package org.eclipse.emf.internal.cdo.transaction; import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.id.CDOIDUtil; +import org.eclipse.emf.cdo.common.revision.CDOReferenceAdjuster; +import org.eclipse.emf.cdo.internal.common.id.CDOIDTempObjectExternalImpl; +import org.eclipse.emf.cdo.spi.common.revision.CDOIDMapper; import org.eclipse.emf.cdo.transaction.CDOSavepoint; import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.emf.cdo.transaction.CDOXATransaction; @@ -30,6 +34,8 @@ 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.ecore.EObject; +import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.spi.cdo.CDOSessionProtocol; import org.eclipse.emf.spi.cdo.CDOTransactionStrategy; import org.eclipse.emf.spi.cdo.InternalCDOTransaction; @@ -105,6 +111,8 @@ public class CDOXATransactionImpl implements InternalCDOXATransaction private CDOXAInternalAdapter internalAdapter = new CDOXAInternalAdapter(); + private Map<EObject, CDOIDTempObjectExternalImpl> objectToID = new HashMap<EObject, CDOIDTempObjectExternalImpl>(); + public CDOXATransactionImpl() { } @@ -161,6 +169,18 @@ public class CDOXATransactionImpl implements InternalCDOXATransaction viewSet.eAdapters().remove(internalAdapter); }; + public synchronized CDOIDTempObjectExternalImpl getCDOIDExternalTemp(EObject object) + { + CDOIDTempObjectExternalImpl cdoID = objectToID.get(object); + if (cdoID == null) + { + cdoID = (CDOIDTempObjectExternalImpl)CDOIDUtil.createTempObjectExternal(EcoreUtil.getURI(object).toString()); + objectToID.put(object, cdoID); + } + + return cdoID; + } + public void add(InternalCDOTransaction view, CDOID object) { synchronized (requestedCDOID) @@ -259,6 +279,8 @@ public class CDOXATransactionImpl implements InternalCDOXATransaction progressMonitor.beginTask(Messages.getString("CDOXATransactionImpl.4"), 3); //$NON-NLS-1$ int phase = 0; + objectToID.clear(); + for (InternalCDOTransaction transaction : transactions) { InternalCDOCommitContext context = transaction.createCommitContext(); @@ -467,7 +489,14 @@ public class CDOXATransactionImpl implements InternalCDOXATransaction @Override protected void handle(CDOXACommitContextImpl xaContext, IProgressMonitor progressMonitor) throws Exception { + CDOIDMapper idMapper = new CDOIDMapper(); + + CDOReferenceAdjuster referenceAdjuster = xaContext.createAdjuster(idMapper); + + CDOSavepointImpl.applyReferenceAdjuster(xaContext, referenceAdjuster); + xaContext.preCommit(); + CommitTransactionResult result = null; if (xaContext.getTransaction().isDirty()) { @@ -552,6 +581,7 @@ public class CDOXATransactionImpl implements InternalCDOXATransaction CDOSessionProtocol sessionProtocol = xaContext.getTransaction().getSession().getSessionProtocol(); OMMonitor monitor = new EclipseMonitor(progressMonitor); CommitTransactionResult result = sessionProtocol.commitTransactionCancel(xaContext, monitor); + xaContext.commitFail(); check_result(result); } }; 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 53e435b460..d9ad1adce4 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 @@ -893,14 +893,6 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView public Object convertObjectToID(Object potentialObject) { - return convertObjectToID(potentialObject, false); - } - - /** - * @since 2.0 - */ - public Object convertObjectToID(Object potentialObject, boolean onlyPersistedID) - { if (potentialObject instanceof CDOID) { return potentialObject; @@ -911,7 +903,7 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView if (potentialObject instanceof InternalCDOObject) { InternalCDOObject object = (InternalCDOObject)potentialObject; - CDOID id = getID(object, onlyPersistedID); + CDOID id = getID(object); if (id != null) { return id; @@ -924,7 +916,7 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView InternalCDOObject object = FSMUtil.getLegacyAdapter(((InternalEObject)potentialObject).eAdapters()); if (object != null) { - CDOID id = getID(object, onlyPersistedID); + CDOID id = getID(object); if (id != null) { return id; @@ -943,7 +935,7 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView return potentialObject; } - private CDOID getID(InternalCDOObject object, boolean onlyPersistedID) + private CDOID getID(InternalCDOObject object) { // if (onlyPersistedID) // { @@ -952,6 +944,11 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView // return null; // } // } + // Need to check the state of the object before doing anything else. + if (FSMUtil.isTransient(object)) + { + return null; + } CDOView view = object.cdoView(); if (view == this) diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOTransactionStrategy.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOTransactionStrategy.java index af3d83ed82..53bdeb8dd4 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOTransactionStrategy.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOTransactionStrategy.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 diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOTransaction.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOTransaction.java index 17b5ab1c1a..83972deefd 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOTransaction.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOTransaction.java @@ -13,10 +13,11 @@ package org.eclipse.emf.spi.cdo; import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.common.id.CDOIDTemp; -import org.eclipse.emf.cdo.common.revision.CDOReferenceAdjustable; +import org.eclipse.emf.cdo.common.revision.CDOReferenceAdjuster; import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta; import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta; import org.eclipse.emf.cdo.eresource.CDOResourceFolder; +import org.eclipse.emf.cdo.spi.common.revision.CDOIDMapper; import org.eclipse.emf.cdo.transaction.CDOCommitContext; import org.eclipse.emf.cdo.transaction.CDOSavepoint; import org.eclipse.emf.cdo.transaction.CDOTransaction; @@ -30,7 +31,7 @@ import java.util.Set; * @author Simon McDuff * @since 2.0 */ -public interface InternalCDOTransaction extends CDOTransaction, InternalCDOView, CDOReferenceAdjustable +public interface InternalCDOTransaction extends CDOTransaction, InternalCDOView { public InternalCDOCommitContext createCommitContext(); @@ -75,5 +76,10 @@ public interface InternalCDOTransaction extends CDOTransaction, InternalCDOView, public void preCommit(); public void postCommit(CommitTransactionResult result); + + /** + * @since 3.0 + */ + public CDOReferenceAdjuster createAdjuster(CDOIDMapper idMapper); } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java index 26317cbccc..fb0770abf4 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java @@ -96,11 +96,6 @@ public interface InternalCDOView extends CDOView, ILifecycle /** * @since 3.0 */ - public Object convertObjectToID(Object potentialObject, boolean onlyPersistedID); - - /** - * @since 3.0 - */ public InternalEObject convertIDToObject(Object potentialID); /** |