diff options
Diffstat (limited to 'plugins/org.eclipse.emf.cdo')
7 files changed, 414 insertions, 94 deletions
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOCommitContext.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOCommitContext.java index 4905d74085..4620ed9218 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOCommitContext.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOCommitContext.java @@ -55,11 +55,6 @@ public interface CDOCommitContext public CDOTransaction getTransaction(); /** - * @since 4.1 - */ - public boolean isAutoReleaseLocks(); - - /** * @since 4.0 */ public boolean isPartialCommit(); @@ -80,11 +75,6 @@ public interface CDOCommitContext public List<CDOPackageUnit> getNewPackageUnits(); /** - * @since 4.1 - */ - public Collection<CDOLockState> getLocksOnNewObjects(); - - /** * Returns a map of the new {@link CDOObject objects} that are to be committed with this commit context. */ public Map<CDOID, CDOObject> getNewObjects(); @@ -108,4 +98,21 @@ public interface CDOCommitContext * @since 4.0 */ public Collection<CDOLob<?>> getLobs(); + + /** + * @since 4.1 + * @deprecated As of 4.5 no longer supported. See {@link #getUnlocksOnChangedObjects()}. + */ + @Deprecated + public boolean isAutoReleaseLocks(); + + /** + * @since 4.1 + */ + public Collection<CDOLockState> getLocksOnNewObjects(); + + /** + * @since 4.5 + */ + public Collection<CDOID> getUnlocksOnChangedObjects(); } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransaction.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransaction.java index 95d4460e3a..a29c90e108 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransaction.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOTransaction.java @@ -292,24 +292,84 @@ public interface CDOTransaction extends CDOView, CDOCommonTransaction, CDOUserTr public void setStaleReferenceCleaner(CDOStaleReferenceCleaner staleReferenceCleaner); /** - * Returns true if locks in this view will be removes when {@link CDOTransaction#commit()} or - * {@link CDOTransaction#rollback()} is called. + * Returns <code>true</code> if locks in this transaction will be released when {@link CDOTransaction#commit()} or + * {@link CDOTransaction#rollback()} are called, <code>false</code> otherwise. * <p> - * Default value is true. + * The default value is <code>true</code>. + * + * @see #getAutoReleaseLocksExemptions() */ public boolean isAutoReleaseLocksEnabled(); /** - * Specifies whether locks in this view will be removed when {@link CDOTransaction#commit()} or - * {@link CDOTransaction#rollback()} is called. + * Specifies whether locks in this transaction will be released when {@link CDOTransaction#commit()} or + * {@link CDOTransaction#rollback()} are called. * <p> - * If false all locks are kept. + * If set to <code>false</code> all locks will be kept when {@link CDOTransaction#commit()} or + * {@link CDOTransaction#rollback()} are called. * <p> - * Default value is true. + * The default value is <code>true</code>. + * + * @see #getAutoReleaseLocksExemptions() */ public void setAutoReleaseLocksEnabled(boolean on); /** + * Returns the set of {@link EObject objects} that are to be treated as exemptions to the {@link #isAutoReleaseLocksEnabled()} option. + * <p> + * That means: + * <p> + * <ul> + * <li> If {@link #isAutoReleaseLocksEnabled()} returns <code>true</code>, the locks on the objects in this set are <b>not</b> released + * when {@link CDOTransaction#commit()} or {@link CDOTransaction#rollback()} are called. + * <li> If {@link #isAutoReleaseLocksEnabled()} returns <code>false</code>, the locks on the objects in this set <b>are</b> released nevertheless + * when {@link CDOTransaction#commit()} or {@link CDOTransaction#rollback()} are called. + * </ul> + * <p> + * The returned set is unmodifiable. To modify the set use the {@link #clearAutoReleaseLocksExemptions() clearAutoReleaseLocksExemptions()}, + * {@link #addAutoReleaseLocksExemptions(boolean, EObject...) addAutoReleaseLocksExemption()}, + * and {@link #removeAutoReleaseLocksExemptions(boolean, EObject...) removeAutoReleaseLocksExemption()} methods. + * <p> + * <b>Implementation note</b>: This set stores weak references to the contained objects. + * + * @see #clearAutoReleaseLocksExemptions() + * @see #addAutoReleaseLocksExemptions(boolean, EObject...) + * @see #removeAutoReleaseLocksExemptions(boolean, EObject...) + * @since 4.5 + */ + public Set<? extends EObject> getAutoReleaseLocksExemptions(); + + /** + * Clears the set of {@link EObject objects} that are to be treated as exemptions to the {@link #isAutoReleaseLocksEnabled()} option. + * + * @see #getAutoReleaseLocksExemptions() + * @see #addAutoReleaseLocksExemptions(boolean, EObject...) + * @see #removeAutoReleaseLocksExemptions(boolean, EObject...) + * @since 4.5 + */ + public void clearAutoReleaseLocksExemptions(); + + /** + * Adds the given {@link EObject object} to the set of objects that are to be treated as exemptions to the {@link #isAutoReleaseLocksEnabled()} option. + * + * @see #getAutoReleaseLocksExemptions() + * @see #clearAutoReleaseLocksExemptions() + * @see #removeAutoReleaseLocksExemptions(boolean, EObject...) + * @since 4.5 + */ + public void addAutoReleaseLocksExemptions(boolean recursive, EObject... objects); + + /** + * Removes the given {@link EObject object} from the set of objects that are to be treated as exemptions to the {@link #isAutoReleaseLocksEnabled()} option. + * + * @see #getAutoReleaseLocksExemptions() + * @see #clearAutoReleaseLocksExemptions() + * @see #addAutoReleaseLocksExemptions(boolean, EObject...) + * @since 4.5 + */ + public void removeAutoReleaseLocksExemptions(boolean recursive, EObject... objects); + + /** * Returns the number of milliseconds to wait for the transaction update when {@link CDOTransaction#commit()} is called. * <p> * Default value is 10000. @@ -367,7 +427,8 @@ public interface CDOTransaction extends CDOView, CDOCommonTransaction, CDOUserTr /** * An {@link IOptionsEvent options event} fired from transaction {@link CDOTransaction#options() options} when the - * {@link Options#setAutoReleaseLocksEnabled(boolean) auto release locks} option has changed. + * {@link Options#setAutoReleaseLocksEnabled(boolean) auto release locks enabled} or + * {@link Options#getAutoReleaseLocksExemptions() auto release locks exemptions} options have changed. * * @author Eike Stepper * @since 3.0 @@ -376,6 +437,31 @@ public interface CDOTransaction extends CDOView, CDOCommonTransaction, CDOUserTr */ public interface AutoReleaseLocksEvent extends IOptionsEvent { + /** + * An {@link AutoReleaseLocksEvent auto release locks options event} fired from transaction {@link CDOTransaction#options() options} when the + * {@link Options#setAutoReleaseLocksEnabled(boolean) auto release locks enabled} option has changed. + * + * @author Eike Stepper + * @since 4.5 + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ + public interface AutoReleaseLocksEnabledEvent extends AutoReleaseLocksEvent + { + } + + /** + * An {@link AutoReleaseLocksEvent auto release locks options event} fired from transaction {@link CDOTransaction#options() options} when the + * {@link Options#getAutoReleaseLocksExemptions() auto release locks exemptions} option has changed. + * + * @author Eike Stepper + * @since 4.5 + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ + public interface AutoReleaseLocksExemptionsEvent extends AutoReleaseLocksEvent + { + } } /** 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 41cd6b114b..6e7ce0a636 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 @@ -88,8 +88,10 @@ import org.eclipse.emf.spi.cdo.FSMUtil; import org.eclipse.emf.spi.cdo.InternalCDOObject; import org.eclipse.emf.spi.cdo.InternalCDOView; +import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.concurrent.locks.Lock; @@ -592,6 +594,20 @@ public final class CDOUtil } /** + * @since 4.5 + */ + public static List<? extends CDOObject> getCDOObjects(EObject... objects) + { + List<CDOObject> result = new ArrayList<CDOObject>(); + for (EObject object : objects) + { + result.add(getCDOObject(object)); + } + + return result; + } + + /** * @since 4.4 */ public static boolean isCDOObject(EObject object) 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 c80de5cabe..41d3c6c0dc 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 @@ -96,6 +96,8 @@ import org.eclipse.emf.cdo.transaction.CDOMerger; import org.eclipse.emf.cdo.transaction.CDOSavepoint; import org.eclipse.emf.cdo.transaction.CDOStaleReferenceCleaner; import org.eclipse.emf.cdo.transaction.CDOTransaction; +import org.eclipse.emf.cdo.transaction.CDOTransaction.Options.AutoReleaseLocksEvent.AutoReleaseLocksEnabledEvent; +import org.eclipse.emf.cdo.transaction.CDOTransaction.Options.AutoReleaseLocksEvent.AutoReleaseLocksExemptionsEvent; import org.eclipse.emf.cdo.transaction.CDOTransactionConflictEvent; import org.eclipse.emf.cdo.transaction.CDOTransactionFinishedEvent; import org.eclipse.emf.cdo.transaction.CDOTransactionHandler; @@ -146,6 +148,7 @@ import org.eclipse.net4j.util.transaction.TransactionException; import org.eclipse.emf.common.notify.NotificationChain; import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; @@ -176,7 +179,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.text.MessageFormat; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -187,6 +189,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.WeakHashMap; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicInteger; @@ -3640,8 +3643,6 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa private CDOCommitData commitData; - private Collection<CDOLockState> locksOnNewObjects; - private Map<CDOID, CDOObject> newObjects; private Map<CDOID, CDOObject> detachedObjects; @@ -3652,6 +3653,10 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa private Map<ByteArrayWrapper, CDOLob<?>> lobs = new HashMap<ByteArrayWrapper, CDOLob<?>>(); + private List<CDOLockState> locksOnNewObjects = new ArrayList<CDOLockState>(); + + private List<CDOID> unlocksOnChangedObjects = new ArrayList<CDOID>(); + public CDOCommitContextImpl(InternalCDOTransaction transaction) { this.transaction = transaction; @@ -3660,6 +3665,8 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa private void calculateCommitData() { + OptionsImpl options = (OptionsImpl)transaction.options(); + List<CDOPackageUnit> newPackageUnits = analyzeNewPackages(); newObjects = filterCommittables(transaction.getNewObjects()); @@ -3667,6 +3674,15 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa for (CDOObject newObject : newObjects.values()) { revisions.add(newObject.cdoRevision()); + + CDOLockState lockState = getLockState(newObject); + if (lockState != null) + { + if (!options.isEffectiveAutoReleaseLock(newObject)) + { + locksOnNewObjects.add(lockState); + } + } } revisionDeltas = filterCommittables(transaction.getRevisionDeltas()); @@ -3699,9 +3715,17 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa } dirtyObjects = filterCommittables(transaction.getDirtyObjects()); - - CDOLockState[] locksOnNewObjectsArray = getLockStates(newObjects.keySet(), false); - locksOnNewObjects = Arrays.asList(locksOnNewObjectsArray); + for (CDOObject dirtyObject : dirtyObjects.values()) + { + CDOLockState lockState = getLockState(dirtyObject); + if (lockState != null) + { + if (options.isEffectiveAutoReleaseLock(dirtyObject)) + { + unlocksOnChangedObjects.add(dirtyObject.cdoID()); + } + } + } commitData = CDOCommitInfoUtil.createCommitData(newPackageUnits, revisions, deltas, detached); } @@ -3757,11 +3781,6 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa return isPartialCommit; } - public boolean isAutoReleaseLocks() - { - return transaction.options().isAutoReleaseLocksEnabled(); - } - public String getCommitComment() { return transaction.getCommitComment(); @@ -3787,11 +3806,6 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa return commitData.getNewPackageUnits(); } - public Collection<CDOLockState> getLocksOnNewObjects() - { - return locksOnNewObjects; - } - public Map<CDOID, CDOObject> getDetachedObjects() { return detachedObjects; @@ -3807,6 +3821,22 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa return lobs.values(); } + @Deprecated + public boolean isAutoReleaseLocks() + { + return transaction.options().isAutoReleaseLocksEnabled(); + } + + public Collection<CDOLockState> getLocksOnNewObjects() + { + return locksOnNewObjects; + } + + public List<CDOID> getUnlocksOnChangedObjects() + { + return unlocksOnChangedObjects; + } + public void preCommit() { if (isDirty()) @@ -3991,6 +4021,8 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa fireEvent(new FinishedEvent(idMappings), listeners); } + unlock new objects, if needed! + CDOLockState[] newLockStates = result.getNewLockStates(); if (newLockStates != null) { @@ -4175,12 +4207,14 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa { private CDOUndoDetector undoDetector = DEFAULT_UNDO_DETECTOR; - private List<CDOConflictResolver> conflictResolvers = new ArrayList<CDOConflictResolver>(); + private final List<CDOConflictResolver> conflictResolvers = new ArrayList<CDOConflictResolver>(); private CDOStaleReferenceCleaner staleReferenceCleaner = CDOStaleReferenceCleaner.DEFAULT; private boolean autoReleaseLocksEnabled = true; + private final Map<EObject, Boolean> autoReleaseLocksExemptions = new WeakHashMap<EObject, Boolean>(); + private long commitInfoTimeout = DEFAULT_COMMIT_INFO_TIMEOUT; public OptionsImpl() @@ -4414,7 +4448,50 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa if (autoReleaseLocksEnabled != on) { autoReleaseLocksEnabled = on; - event = new AutoReleaseLocksEventImpl(); + event = new AutoReleaseLocksEnabledEventImpl(); + } + } + finally + { + unlockView(); + } + } + + fireEvent(event); + } + + public Set<? extends EObject> getAutoReleaseLocksExemptions() + { + synchronized (getViewMonitor()) + { + lockView(); + + try + { + return new HashSet<EObject>(autoReleaseLocksExemptions.keySet()); + } + finally + { + unlockView(); + } + } + } + + public void clearAutoReleaseLocksExemptions() + { + checkActive(); + + IEvent event = null; + synchronized (getViewMonitor()) + { + lockView(); + + try + { + if (!autoReleaseLocksExemptions.isEmpty()) + { + autoReleaseLocksExemptions.clear(); + event = new AutoReleaseLocksExemptionsEventImpl(); } } finally @@ -4426,6 +4503,97 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa fireEvent(event); } + public void addAutoReleaseLocksExemptions(boolean recursive, EObject... objects) + { + checkActive(); + + IEvent event = null; + synchronized (getViewMonitor()) + { + lockView(); + + try + { + for (EObject object : objects) + { + if (autoReleaseLocksExemptions.put(object, Boolean.TRUE) == null) + { + event = new AutoReleaseLocksExemptionsEventImpl(); + } + + if (recursive) + { + for (TreeIterator<EObject> it = object.eAllContents(); it.hasNext();) + { + EObject child = it.next(); + if (autoReleaseLocksExemptions.put(child, Boolean.TRUE) == null && event == null) + { + event = new AutoReleaseLocksExemptionsEventImpl(); + } + } + } + } + } + finally + { + unlockView(); + } + } + + fireEvent(event); + } + + public void removeAutoReleaseLocksExemptions(boolean recursive, EObject... objects) + { + checkActive(); + + IEvent event = null; + synchronized (getViewMonitor()) + { + lockView(); + + try + { + for (EObject object : objects) + { + if (autoReleaseLocksExemptions.remove(object) != null) + { + event = new AutoReleaseLocksExemptionsEventImpl(); + } + + if (recursive) + { + for (TreeIterator<EObject> it = object.eAllContents(); it.hasNext();) + { + EObject child = it.next(); + if (autoReleaseLocksExemptions.put(child, Boolean.TRUE) == null && event == null) + { + event = new AutoReleaseLocksExemptionsEventImpl(); + } + } + } + } + } + finally + { + unlockView(); + } + } + + fireEvent(event); + } + + public boolean isEffectiveAutoReleaseLock(CDOObject newObject) + { + boolean effectiveAutoReleaseLock = autoReleaseLocksEnabled; + if (autoReleaseLocksExemptions.containsKey(newObject)) + { + effectiveAutoReleaseLock = !effectiveAutoReleaseLock; + } + + return effectiveAutoReleaseLock; + } + public long getCommitInfoTimeout() { return commitInfoTimeout; @@ -4499,11 +4667,25 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa /** * @author Eike Stepper */ - private final class AutoReleaseLocksEventImpl extends OptionsEvent implements AutoReleaseLocksEvent + private final class AutoReleaseLocksEnabledEventImpl extends OptionsEvent implements AutoReleaseLocksEnabledEvent + { + private static final long serialVersionUID = 1L; + + public AutoReleaseLocksEnabledEventImpl() + { + super(OptionsImpl.this); + } + } + + /** + * @author Eike Stepper + */ + private final class AutoReleaseLocksExemptionsEventImpl extends OptionsEvent + implements AutoReleaseLocksExemptionsEvent { private static final long serialVersionUID = 1L; - public AutoReleaseLocksEventImpl() + public AutoReleaseLocksExemptionsEventImpl() { super(OptionsImpl.this); } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOUndoDetectorImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOUndoDetectorImpl.java index 681dbc538d..1a9aa4d135 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOUndoDetectorImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOUndoDetectorImpl.java @@ -94,7 +94,7 @@ public class CDOUndoDetectorImpl implements CDOUndoDetector } /** - * @deprecated As of CDO 4.5 {@link #detectUndo(CDOTransaction, CDORevision, CDORevision, CDOFeatureDelta)} is called. + * @deprecated As of 4.5 {@link #detectUndo(CDOTransaction, CDORevision, CDORevision, CDOFeatureDelta)} is called. */ @Deprecated protected boolean detectUndoContainer(InternalCDORevision cleanRevision, InternalCDORevision currentRevision) 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 e475279359..a7b3dfc306 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 @@ -119,11 +119,6 @@ public class CDOXACommitContextImpl implements InternalCDOXACommitContext return delegateCommitContext.getTransaction(); } - public boolean isAutoReleaseLocks() - { - return delegateCommitContext.isAutoReleaseLocks(); - } - public boolean isPartialCommit() { return delegateCommitContext.isPartialCommit(); @@ -159,11 +154,6 @@ public class CDOXACommitContextImpl implements InternalCDOXACommitContext return delegateCommitContext.getNewPackageUnits(); } - public Collection<CDOLockState> getLocksOnNewObjects() - { - return delegateCommitContext.getLocksOnNewObjects(); - } - public Map<CDOID, CDOObject> getDetachedObjects() { return delegateCommitContext.getDetachedObjects(); @@ -179,6 +169,22 @@ public class CDOXACommitContextImpl implements InternalCDOXACommitContext return delegateCommitContext.getLobs(); } + @Deprecated + public boolean isAutoReleaseLocks() + { + return delegateCommitContext.isAutoReleaseLocks(); + } + + public Collection<CDOLockState> getLocksOnNewObjects() + { + return delegateCommitContext.getLocksOnNewObjects(); + } + + public Collection<CDOID> getUnlocksOnChangedObjects() + { + return delegateCommitContext.getUnlocksOnChangedObjects(); + } + public Object call() throws Exception { state.handle(this, progressMonitor); 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 694efefc37..27081656b1 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 @@ -99,6 +99,7 @@ import org.eclipse.net4j.util.ref.ReferenceValueMap; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.InternalEObject; import org.eclipse.emf.ecore.util.EcoreUtil; @@ -121,6 +122,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -361,6 +363,16 @@ public class CDOViewImpl extends AbstractCDOView implements IExecutorServiceProv { CDOLockState lockState = createUpdatedLockStateForNewObject(object, lockType, true); locksOnNewObjects.add(lockState); + + if (recursive) + { + for (TreeIterator<EObject> it = object.eAllContents(); it.hasNext();) + { + CDOObject child = CDOUtil.getCDOObject(it.next()); + lockState = createUpdatedLockStateForNewObject(child, lockType, true); + locksOnNewObjects.add(lockState); + } + } } else { @@ -429,8 +441,12 @@ public class CDOViewImpl extends AbstractCDOView implements IExecutorServiceProv } } - CDOLockState[] locksOnNewObjectsArray = locksOnNewObjects.toArray(new CDOLockState[locksOnNewObjects.size()]); - updateLockStates(locksOnNewObjectsArray); + int locksOnNewObjectsCount = locksOnNewObjects.size(); + if (locksOnNewObjectsCount != 0) + { + CDOLockState[] locksOnNewObjectsArray = locksOnNewObjects.toArray(new CDOLockState[locksOnNewObjectsCount]); + updateLockStates(locksOnNewObjectsArray); + } if (result != null) { @@ -637,6 +653,16 @@ public class CDOViewImpl extends AbstractCDOView implements IExecutorServiceProv { CDOLockState lockState = createUpdatedLockStateForNewObject(object, lockType, false); locksOnNewObjects.add(lockState); + + if (recursive) + { + for (TreeIterator<EObject> it = object.eAllContents(); it.hasNext();) + { + CDOObject child = CDOUtil.getCDOObject(it.next()); + lockState = createUpdatedLockStateForNewObject(child, lockType, false); + locksOnNewObjects.add(lockState); + } + } } else { @@ -984,83 +1010,80 @@ public class CDOViewImpl extends AbstractCDOView implements IExecutorServiceProv try { - List<CDOID> missing = new LinkedList<CDOID>(); - List<CDOLockState> lockStates = new LinkedList<CDOLockState>(); - List<CDOLockState> locksOnNewObjects = new ArrayList<CDOLockState>(ids.size()); + Set<CDOID> missingIDs = new LinkedHashSet<CDOID>(); + List<CDOLockState> result = new LinkedList<CDOLockState>(); for (CDOID id : ids) { - CDOLockState lockState = null; InternalCDOObject object = getObject(id, false); if (object != null) { - lockState = this.lockStates.get(object); - } - - if (lockState != null) - { - lockStates.add(lockState); - } - else if (loadOnDemand && object != null && FSMUtil.isNew(object)) - { - Object lockedObject = getLockTarget(object); // CDOID or CDOIDAndBranch - CDOLockState defaultLockState = CDOLockUtil.createLockState(lockedObject); - locksOnNewObjects.add(defaultLockState); - lockStates.add(defaultLockState); - } - else - { - missing.add(id); + CDOLockState lockState = lockStates.get(object); + if (lockState != null) + { + result.add(lockState); + } + else if (loadOnDemand) + { + missingIDs.add(id); + } } } - if (loadOnDemand && (missing.size() > 0 || ids.isEmpty())) + if (loadOnDemand && (!missingIDs.isEmpty() || ids.isEmpty())) { CDOSessionProtocol sessionProtocol = session.getSessionProtocol(); - CDOLockState[] loadedLockStates = sessionProtocol.getLockStates(viewID, missing, CDOLockState.DEPTH_NONE); - List<CDOLockState> newLockStateForCache = new ArrayList<CDOLockState>( - loadedLockStates.length + missing.size()); + CDOLockState[] loadedLockStates = sessionProtocol.getLockStates(viewID, missingIDs, CDOLockState.DEPTH_NONE); + + List<CDOLockState> lockStatesToUpdate = options().isLockNotificationEnabled() + ? new ArrayList<CDOLockState>(loadedLockStates.length) : null; + for (CDOLockState loadedLockState : loadedLockStates) { - lockStates.add(loadedLockState); - newLockStateForCache.add(loadedLockState); + result.add(loadedLockState); - CDOID cdoID = CDOIDUtil.getCDOID(loadedLockState.getLockedObject()); - if (cdoID != null) + if (lockStatesToUpdate != null) { - missing.remove(cdoID); + lockStatesToUpdate.add(loadedLockState); + } + + CDOID id = CDOIDUtil.getCDOID(loadedLockState.getLockedObject()); + if (id != null) + { + missingIDs.remove(id); } } - for (CDOID missingLockStateForCDOID : missing) + for (CDOID missingLockStateForCDOID : missingIDs) { - Object target; + Object lockTarget; InternalCDOObject object = getObject(missingLockStateForCDOID, false); if (object != null) { - target = getLockTarget(object); // CDOID or CDOIDAndBranch + lockTarget = getLockTarget(object); // CDOID or CDOIDAndBranch } else { - target = missingLockStateForCDOID; + lockTarget = missingLockStateForCDOID; } - CDOLockState defaultLockState = CDOLockUtil.createLockState(target); - lockStates.add(defaultLockState); - newLockStateForCache.add(defaultLockState); + CDOLockState defaultLockState = CDOLockUtil.createLockState(lockTarget); + result.add(defaultLockState); + + if (lockStatesToUpdate != null) + { + lockStatesToUpdate.add(defaultLockState); + } } - if (options().isLockNotificationEnabled()) + if (lockStatesToUpdate != null && !lockStatesToUpdate.isEmpty()) { - updateLockStates(newLockStateForCache.toArray(new CDOLockState[newLockStateForCache.size()])); + updateLockStates(lockStatesToUpdate.toArray(new CDOLockState[lockStatesToUpdate.size()])); } } - CDOLockState[] locksOnNewObjectsArray = locksOnNewObjects.toArray(new CDOLockState[locksOnNewObjects.size()]); - updateLockStates(locksOnNewObjectsArray); - - return lockStates.toArray(new CDOLockState[lockStates.size()]); + return result.toArray(new CDOLockState[result.size()]); } finally { |