diff options
4 files changed, 43 insertions, 17 deletions
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/MutableSyncInfoSet.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/MutableSyncInfoSet.java index ef0c2beba..ed85610ba 100644 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/MutableSyncInfoSet.java +++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/MutableSyncInfoSet.java @@ -31,7 +31,7 @@ public class MutableSyncInfoSet extends SyncInfoSet { public synchronized void remove(IResource local) { IPath path = local.getFullPath(); SyncInfo info = (SyncInfo)resources.remove(path); - changes.removed(local); + changes.removed(local, info); if (info != null) { statistics.remove(info); } diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncSetChangedEvent.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncSetChangedEvent.java index 4ae088bf6..811e7f562 100644 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncSetChangedEvent.java +++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncSetChangedEvent.java @@ -40,10 +40,24 @@ public class SyncSetChangedEvent implements ISyncInfoSetChangeEvent { } public void added(SyncInfo info) { - addedResources.add(info); + if (removedResources.contains(info.getLocal())) { + // A removal followed by an addition is treated as a change + removedResources.remove(info.getLocal()); + changed(info); + } else { + addedResources.add(info); + } } - public void removed(IResource resource) { + public void removed(IResource resource, SyncInfo info) { + if (changedResources.contains(info)) { + // No use in reporting the change since it has subsequently been removed + changedResources.remove(info); + } else if (addedResources.contains(info)) { + // An addition followed by a removal can be dropped + addedResources.remove(info); + return; + } removedResources.add(resource); } @@ -55,6 +69,8 @@ public class SyncSetChangedEvent implements ISyncInfoSetChangeEvent { if (addedRoots.contains(root)) { // The root was added and removed which is a no-op addedRoots.remove(root); + } else if (isDescendantOfAddedRoot(root)) { + // Nothing needs to be done since no listeners ever knew about the root } else { // check if the root is a child of an existing root // (in which case it need not be added). @@ -82,21 +98,27 @@ public class SyncSetChangedEvent implements ISyncInfoSetChangeEvent { public void addedRoot(IResource parent) { if (removedRoots.contains(parent)) { - // The root was re-added which is a no-op - // TODO: This is actually a change which needs to be handled somehow. But how? - removedRoots.remove(parent); + // The root was re-added. Just removing the removedRoot + // may not give the proper event. + // Since we can't be sure, just force a reset. + reset(); } else { - // do not add the root if it is the child of another added root - for (Iterator iter = addedRoots.iterator(); iter.hasNext();) { - IResource root = (IResource) iter.next(); - if (isParent(root, parent)) { - // There is a higher added root already in the list - return; - } + // only add the root if their isn't a higher root in the list already + if (!isDescendantOfAddedRoot(parent)) { + addedRoots.add(parent); } - addedRoots.add(parent); } - + } + + private boolean isDescendantOfAddedRoot(IResource resource) { + for (Iterator iter = addedRoots.iterator(); iter.hasNext();) { + IResource root = (IResource) iter.next(); + if (isParent(root, resource)) { + // There is a higher added root already in the list + return true; + } + } + return false; } public SyncInfo[] getAddedResources() { diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ReentrantLock.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ReentrantLock.java index 9003195f7..fbae8d65e 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ReentrantLock.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ReentrantLock.java @@ -78,8 +78,8 @@ public class ReentrantLock { if (rule != NULL_SCHEDULING_RULE) { try { Platform.getJobManager().beginRule(rule, monitor); - } catch (OperationCanceledException e) { - // The begin was cancelled. + } catch (RuntimeException e) { + // The begin was cancelled (or some other problem occurred). // Free the scheduling rule and throw the cancel // so the clients of ReentrantLock don't need to // do an endRule when the operation is cancelled. diff --git a/bundles/org.eclipse.team.ui/TODO-syncview.txt b/bundles/org.eclipse.team.ui/TODO-syncview.txt index 0b5101f08..9753feaf5 100644 --- a/bundles/org.eclipse.team.ui/TODO-syncview.txt +++ b/bundles/org.eclipse.team.ui/TODO-syncview.txt @@ -98,4 +98,8 @@ x memory and sync set disposal in syncsetcompare input!!!! VERY IMPORTANT!!! - several places require a resource - e.g. conflict propogation requires a resource but shouldn't (modified to work without a resource) - conflicts do not propogate in comment view +- the test cases starve the subscriber event handler such that an event has additions and removals for the same resources + - this causes failures in the diff tree builders + - although less likely in UI, can still happen + - need tests for these scenarios to ensure generated event is correct after addition and removal
\ No newline at end of file |