Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/AbstractResourceVariantTree.java294
-rw-r--r--bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/IResourceVariantTree.java2
-rw-r--r--bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/ResourceVariantTree.java320
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSCompareSubscriber.java51
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSMergeSubscriber.java78
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSSyncTreeSubscriber.java110
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSWorkspaceSubscriber.java75
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSBaseResourceVariantTree.java (renamed from bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSBaseSynchronizationCache.java)2
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSDescendantResourceVariantTree.java (renamed from bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSDescendantSynchronizationCache.java)4
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSRefreshOperation.java106
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSResourceVariantTree.java197
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSSynchronizationCache.java52
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/MultiTagResourceVariantTree.java45
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SyncInfoCompareInput.java1
14 files changed, 770 insertions, 567 deletions
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/AbstractResourceVariantTree.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/AbstractResourceVariantTree.java
new file mode 100644
index 000000000..c2a47c453
--- /dev/null
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/AbstractResourceVariantTree.java
@@ -0,0 +1,294 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.internal.core.subscribers.caches;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.synchronize.IResourceVariant;
+import org.eclipse.team.internal.core.Assert;
+import org.eclipse.team.internal.core.Policy;
+
+
+/**
+ * This class provides the logic for refreshing and collecting the changes in
+ * a resource variant tree.
+ */
+public abstract class AbstractResourceVariantTree implements IResourceVariantTree {
+
+ /**
+ * Refreshes the resource variant tree for the specified resources and possibly their descendants,
+ * depending on the depth. The default implementation of this method invokes
+ * <code>refresh(IResource, int, IProgressMonitor)</code> for each resource.
+ * Subclasses may override but should either invoke the above mentioned refresh or
+ * <code>collectChanges</code> in order to reconcile the resource variant tree.
+ * @param resources the resources whose variants should be refreshed
+ * @param depth the depth of the refresh (one of <code>IResource.DEPTH_ZERO</code>,
+ * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>)
+ * @param monitor a progress monitor
+ * @return the array of resources whose corresponding varianst have changed
+ * @throws TeamException
+ */
+ public IResource[] refresh(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException {
+ List changedResources = new ArrayList();
+ monitor.beginTask(null, 100 * resources.length);
+ for (int i = 0; i < resources.length; i++) {
+ IResource resource = resources[i];
+ IResource[] changed = refresh(resource, depth, Policy.subMonitorFor(monitor, 100));
+ changedResources.addAll(Arrays.asList(changed));
+ }
+ monitor.done();
+ if (changedResources == null) return new IResource[0];
+ return (IResource[]) changedResources.toArray(new IResource[changedResources.size()]);
+ }
+
+ /**
+ * Helper method invoked from <code>refresh(IResource[], int, IProgressMonitor monitor)</code>
+ * for each resource. The default implementation performs the following steps:
+ * <ol>
+ * <li>obtaine the scheduling rule for the resource
+ * as returned from <code>getSchedulingRule(IResource)</code>.
+ * <li>get the resource variant handle corresponding to the local resource by calling
+ * <code>getRemoteTree</code>.
+ * <li>pass the local resource and the resource variant handle to <code>collectChanges</code>
+ * </ol>
+ * Subclasses may override but should perform roughly the same steps.
+ * @param resource the resoure being refreshed
+ * @param depth the depth of the refresh (one of <code>IResource.DEPTH_ZERO</code>,
+ * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>)
+ * @param monitor a progress monitor
+ * @return the resource's whose variants have changed
+ * @throws TeamException
+ */
+ protected IResource[] refresh(IResource resource, int depth, IProgressMonitor monitor) throws TeamException {
+ IResource[] changedResources = null;
+ monitor.beginTask(null, 100);
+ ISchedulingRule rule = getSchedulingRule(resource);
+ try {
+ Platform.getJobManager().beginRule(rule, monitor);
+ if (!resource.getProject().isAccessible()) {
+ // The project is closed so silently skip it
+ return new IResource[0];
+ }
+
+ monitor.setTaskName(Policy.bind("SynchronizationCacheRefreshOperation.0", resource.getFullPath().makeRelative().toString())); //$NON-NLS-1$
+
+ // build the remote tree only if an initial tree hasn't been provided
+ IResourceVariant tree = fetchVariant(resource, depth, Policy.subMonitorFor(monitor, 70));
+
+ // update the known remote handles
+ IProgressMonitor sub = Policy.infiniteSubMonitorFor(monitor, 30);
+ try {
+ sub.beginTask(null, 64);
+ changedResources = collectChanges(resource, tree, depth, sub);
+ } finally {
+ sub.done();
+ }
+ } finally {
+ Platform.getJobManager().endRule(rule);
+ monitor.done();
+ }
+ if (changedResources == null) return new IResource[0];
+ return changedResources;
+ }
+
+ /**
+ * Return the scheduling rule that should be obtained for the given resource.
+ * This method is invoked from <code>refresh(IResource, int, IProgressMonitor)</code>.
+ * By default, the resource's project is returned. Subclasses may override.
+ * @param resource the resource being refreshed
+ * @return a scheduling rule or <code>null</code>
+ */
+ protected ISchedulingRule getSchedulingRule(IResource resource) {
+ return resource.getProject();
+ }
+
+ /**
+ * Collect the changes in the remote tree to the specified depth.
+ * @param local the local resource being refreshed
+ * @param remote the corresponding resource variant
+ * @param depth the depth of the refresh (one of <code>IResource.DEPTH_ZERO</code>,
+ * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>)
+ * @param monitor a progress monitor
+ * @return the resource's whose variants have changed
+ * @throws TeamException
+ */
+ protected IResource[] collectChanges(IResource local, IResourceVariant remote, int depth, IProgressMonitor monitor) throws TeamException {
+ List changedResources = new ArrayList();
+ collectChanges(local, remote, changedResources, depth, monitor);
+ return (IResource[]) changedResources.toArray(new IResource[changedResources.size()]);
+ }
+
+ /**
+ * Fetch the members of the given resource variant handle. This method may
+ * return members that were fetched when <code>getRemoteTree</code> was called or
+ * may fetch the children directly.
+ * @param variant the resource variant
+ * @param progress a progress monitor
+ * @return the members of the resource variant.
+ */
+ protected abstract IResourceVariant[] fetchMembers(IResourceVariant variant, IProgressMonitor progress) throws TeamException;
+
+ /**
+ * Fetch the resource variant corresponding to the given resource.
+ * The depth
+ * parameter indicates the depth of the refresh operation and also indicates the
+ * depth to which the resource variant's desendants will be traversed.
+ * This method may prefetch the descendants to the provided depth
+ * or may just return the variant handle corresponding to the given
+ * local resource, in which case
+ * the descendant variants will be fetched by <code>fecthMembers(IResourceVariant, IProgressMonitor)</code>.
+ * @param resource the local resource
+ * @param depth the depth of the refresh (one of <code>IResource.DEPTH_ZERO</code>,
+ * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>)
+ * @param monitor a progress monitor
+ * @return the resource variant corresponding to the given local resource
+ */
+ protected abstract IResourceVariant fetchVariant(IResource resource, int depth, IProgressMonitor monitor) throws TeamException;
+
+ private void collectChanges(IResource local, IResourceVariant remote, Collection changedResources, int depth, IProgressMonitor monitor) throws TeamException {
+ boolean changed = setVariant(local, remote);
+ if (changed) {
+ changedResources.add(local);
+ }
+ if (depth == IResource.DEPTH_ZERO) return;
+ Map children = mergedMembers(local, remote, monitor);
+ for (Iterator it = children.keySet().iterator(); it.hasNext();) {
+ IResource localChild = (IResource) it.next();
+ IResourceVariant remoteChild = (IResourceVariant)children.get(localChild);
+ collectChanges(localChild, remoteChild, changedResources,
+ depth == IResource.DEPTH_INFINITE ? IResource.DEPTH_INFINITE : IResource.DEPTH_ZERO,
+ monitor);
+ }
+
+ IResource[] cleared = collectedMembers(local, (IResource[]) children.keySet().toArray(new IResource[children.keySet().size()]));
+ changedResources.addAll(Arrays.asList(cleared));
+ }
+
+ /**
+ * Method that is invoked during collection to let subclasses know which memebers
+ * were collected for the given resource. Implementors should purge any cached
+ * state for children of the local resource that are no longer members. any such resources
+ * should be returned.
+ * @param local the local resource
+ * @param members the collected members
+ * @return any resources that were previously collected whose state has been flushed
+ */
+ protected abstract IResource[] collectedMembers(IResource local, IResource[] members) throws TeamException;
+
+ /**
+ * Set the variant associated with the local resource to the newly fetched resource
+ * variant.
+ * This method is invoked during change collection and should return whether
+ * the variant associated with the lcoal resource has changed
+ * @param local the local resource
+ * @param remote the newly fetched resoure variant
+ * @return <code>true</code> if the resource variant changed
+ * @throws TeamException
+ */
+ protected abstract boolean setVariant(IResource local, IResourceVariant remote) throws TeamException;
+
+ private Map mergedMembers(IResource local, IResourceVariant remote, IProgressMonitor progress) throws TeamException {
+
+ // {IResource -> IResourceVariant}
+ Map mergedResources = new HashMap();
+
+ IResourceVariant[] remoteChildren;
+ if (remote == null) {
+ remoteChildren = new IResourceVariant[0];
+ } else {
+ remoteChildren = fetchMembers(remote, progress);
+ }
+
+
+ IResource[] localChildren = members(local);
+
+ if (remoteChildren.length > 0 || localChildren.length > 0) {
+ Set allSet = new HashSet(20);
+ Map localSet = null;
+ Map remoteSet = null;
+
+ if (localChildren.length > 0) {
+ localSet = new HashMap(10);
+ for (int i = 0; i < localChildren.length; i++) {
+ IResource localChild = localChildren[i];
+ String name = localChild.getName();
+ localSet.put(name, localChild);
+ allSet.add(name);
+ }
+ }
+
+ if (remoteChildren.length > 0) {
+ remoteSet = new HashMap(10);
+ for (int i = 0; i < remoteChildren.length; i++) {
+ IResourceVariant remoteChild = remoteChildren[i];
+ String name = remoteChild.getName();
+ remoteSet.put(name, remoteChild);
+ allSet.add(name);
+ }
+ }
+
+ Iterator e = allSet.iterator();
+ while (e.hasNext()) {
+ String keyChildName = (String) e.next();
+
+ if (progress != null) {
+ if (progress.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ // XXX show some progress?
+ }
+
+ IResource localChild =
+ localSet != null ? (IResource) localSet.get(keyChildName) : null;
+
+ IResourceVariant remoteChild =
+ remoteSet != null ? (IResourceVariant) remoteSet.get(keyChildName) : null;
+
+ if (localChild == null) {
+ // there has to be a remote resource available if we got this far
+ Assert.isTrue(remoteChild != null);
+ boolean isContainer = remoteChild.isContainer();
+ localChild = getResourceChild(local /* parent */, keyChildName, isContainer);
+ }
+ mergedResources.put(localChild, remoteChild);
+ }
+ }
+ return mergedResources;
+ }
+
+ private IResource getResourceChild(IResource parent, String childName, boolean isContainer) {
+ if (parent.getType() == IResource.FILE) {
+ return null;
+ }
+ if (isContainer) {
+ return ((IContainer) parent).getFolder(new Path(childName));
+ } else {
+ return ((IContainer) parent).getFile(new Path(childName));
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/IResourceVariantTree.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/IResourceVariantTree.java
index 5bbfbd1b0..cf8c6fcfe 100644
--- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/IResourceVariantTree.java
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/IResourceVariantTree.java
@@ -34,6 +34,8 @@ public interface IResourceVariantTree {
public abstract IResourceVariant getResourceVariant(IResource resource) throws TeamException;
+ public boolean hasResourceVariant(IResource resource) throws TeamException;
+
/**
* Refreshes the resource variant tree for the specified resources and possibly
* their descendants, depending on the depth.
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/ResourceVariantTree.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/ResourceVariantTree.java
index dd72c87f4..e9747b065 100644
--- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/ResourceVariantTree.java
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/ResourceVariantTree.java
@@ -10,16 +10,15 @@
*******************************************************************************/
package org.eclipse.team.internal.core.subscribers.caches;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.*;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.synchronize.IResourceVariant;
-import org.eclipse.team.internal.core.Assert;
-import org.eclipse.team.internal.core.Policy;
/**
* This class provides the logic for refreshing a resource variant tree that
@@ -29,7 +28,7 @@ import org.eclipse.team.internal.core.Policy;
* a <code>ResourceVariantByteStore</code>. It also accumulates and returns all local resources
* for which the corresponding resource variant has changed.
*/
-public abstract class ResourceVariantTree implements IResourceVariantTree {
+public abstract class ResourceVariantTree extends AbstractResourceVariantTree {
/* (non-Javadoc)
* @see org.eclipse.team.internal.core.subscribers.caches.IResourceVariantTree#members(org.eclipse.core.resources.IResource)
@@ -38,118 +37,29 @@ public abstract class ResourceVariantTree implements IResourceVariantTree {
return getByteStore().members(resource);
}
- /**
- * Refreshes the resource variant tree for the specified resources and possibly their descendants,
- * depending on the depth. The default implementation of this method invokes
- * <code>refresh(IResource, int, IProgressMonitor)</code> for each resource.
- * Subclasses may override but should either invoke the above mentioned refresh or
- * <code>collectChanges</code> in order to reconcile the resource variant tree.
- * @param resources the resources whose variants should be refreshed
- * @param depth the depth of the refresh (one of <code>IResource.DEPTH_ZERO</code>,
- * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>)
- * @param monitor a progress monitor
- * @return the array of resources whose corresponding varianst have changed
- * @throws TeamException
- */
- public IResource[] refresh(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException {
- List changedResources = new ArrayList();
- monitor.beginTask(null, 100 * resources.length);
- for (int i = 0; i < resources.length; i++) {
- IResource resource = resources[i];
- IResource[] changed = refresh(resource, depth, Policy.subMonitorFor(monitor, 100));
- changedResources.addAll(Arrays.asList(changed));
- }
- monitor.done();
- if (changedResources == null) return new IResource[0];
- return (IResource[]) changedResources.toArray(new IResource[changedResources.size()]);
- }
-
- /**
- * Helper method invoked from <code>refresh(IResource[], int, IProgressMonitor monitor)</code>
- * for each resource. The default implementation performs the following steps:
- * <ol>
- * <li>obtaine the scheduling rule for the resource
- * as returned from <code>getSchedulingRule(IResource)</code>.
- * <li>get the resource variant handle corresponding to the local resource by calling
- * <code>getRemoteTree</code>.
- * <li>pass the local resource and the resource variant handle to <code>collectChanges</code>
- * </ol>
- * Subclasses may override but should perform roughly the same steps.
- * @param resource the resoure being refreshed
- * @param depth the depth of the refresh (one of <code>IResource.DEPTH_ZERO</code>,
- * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>)
- * @param monitor a progress monitor
- * @return the resource's whose variants have changed
- * @throws TeamException
- */
- protected IResource[] refresh(IResource resource, int depth, IProgressMonitor monitor) throws TeamException {
- IResource[] changedResources = null;
- monitor.beginTask(null, 100);
- ISchedulingRule rule = getSchedulingRule(resource);
- try {
- Platform.getJobManager().beginRule(rule, monitor);
- if (!resource.getProject().isAccessible()) {
- // The project is closed so silently skip it
- return new IResource[0];
- }
-
- monitor.setTaskName(Policy.bind("SynchronizationCacheRefreshOperation.0", resource.getFullPath().makeRelative().toString())); //$NON-NLS-1$
-
- // build the remote tree only if an initial tree hasn't been provided
- IResourceVariant tree = fetchVariant(resource, depth, Policy.subMonitorFor(monitor, 70));
-
- // update the known remote handles
- IProgressMonitor sub = Policy.infiniteSubMonitorFor(monitor, 30);
- try {
- sub.beginTask(null, 64);
- changedResources = collectChanges(resource, tree, depth, sub);
- } finally {
- sub.done();
- }
- } finally {
- Platform.getJobManager().endRule(rule);
- monitor.done();
- }
- if (changedResources == null) return new IResource[0];
- return changedResources;
- }
-
- /**
- * Return the scheduling rule that should be obtained for the given resource.
- * This method is invoked from <code>refresh(IResource, int, IProgressMonitor)</code>.
- * By default, the resource's project is returned. Subclasses may override.
- * @param resource the resource being refreshed
- * @return a scheduling rule or <code>null</code>
+ /* (non-Javadoc)
+ * @see org.eclipse.team.internal.core.subscribers.caches.IResourceVariantTree#hasResourceVariant(org.eclipse.core.resources.IResource)
*/
- protected ISchedulingRule getSchedulingRule(IResource resource) {
- return resource.getProject();
+ public boolean hasResourceVariant(IResource resource) throws TeamException {
+ return getByteStore().getBytes(resource) != null;
}
- /**
- * Collect the changes in the remote tree to the specified depth.
- * @param local the local resource being refreshed
- * @param remote the corresponding resource variant
- * @param depth the depth of the refresh (one of <code>IResource.DEPTH_ZERO</code>,
- * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>)
- * @param monitor a progress monitor
- * @return the resource's whose variants have changed
- * @throws TeamException
+ /* (non-Javadoc)
+ * @see org.eclipse.team.internal.core.subscribers.caches.AbstractResourceVariantTree#setVariant(org.eclipse.core.resources.IResource, org.eclipse.team.core.synchronize.IResourceVariant)
*/
- protected IResource[] collectChanges(IResource local, IResourceVariant remote, int depth, IProgressMonitor monitor) throws TeamException {
- List changedResources = new ArrayList();
- collectChanges(local, remote, changedResources, depth, monitor);
- return (IResource[]) changedResources.toArray(new IResource[changedResources.size()]);
+ protected boolean setVariant(IResource local, IResourceVariant remote) throws TeamException {
+ ResourceVariantByteStore cache = getByteStore();
+ byte[] newRemoteBytes = getBytes(local, remote);
+ boolean changed;
+ if (newRemoteBytes == null) {
+ changed = cache.deleteBytes(local);
+ } else {
+ changed = cache.setBytes(local, newRemoteBytes);
+ }
+ return changed;
}
/**
- * Get the byte store that is used to cache the serialization bytes
- * for the resource variants of this tree. A byte store is used
- * to reduce the memory footprint of the tree.
- * @return the resource variant tree that is being refreshed.
- */
- protected abstract ResourceVariantByteStore getByteStore();
-
- /**
* Get the bytes to be stored in the <code>ResourceVariantByteStore</code>
* from the given resource variant.
* @param local the local resource
@@ -157,81 +67,47 @@ public abstract class ResourceVariantTree implements IResourceVariantTree {
* @return the bytes for the resource variant.
*/
protected abstract byte[] getBytes(IResource local, IResourceVariant remote) throws TeamException;
-
- /**
- * Fetch the members of the given resource variant handle. This method may
- * return members that were fetched when <code>getRemoteTree</code> was called or
- * may fetch the children directly.
- * @param variant the resource variant
- * @param progress a progress monitor
- * @return the members of the resource variant.
- */
- protected abstract IResourceVariant[] fetchMembers(IResourceVariant variant, IProgressMonitor progress) throws TeamException;
- /**
- * Fetch the resource variant corresponding to the given resource.
- * The depth
- * parameter indicates the depth of the refresh operation and also indicates the
- * depth to which the resource variant's desendants will be traversed.
- * This method may prefetch the descendants to the provided depth
- * or may just return the variant handle corresponding to the given
- * local resource, in which case
- * the descendant variants will be fetched by <code>fecthMembers(IResourceVariant, IProgressMonitor)</code>.
- * @param resource the local resource
- * @param depth the depth of the refresh (one of <code>IResource.DEPTH_ZERO</code>,
- * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>)
- * @param monitor a progress monitor
- * @return the resource variant corresponding to the given local resource
+ /* (non-Javadoc)
+ * @see org.eclipse.team.internal.core.subscribers.caches.AbstractResourceVariantTree#collectedMembers(org.eclipse.core.resources.IResource, org.eclipse.core.resources.IResource[])
*/
- protected abstract IResourceVariant fetchVariant(IResource resource, int depth, IProgressMonitor monitor) throws TeamException;
-
- private void collectChanges(IResource local, IResourceVariant remote, Collection changedResources, int depth, IProgressMonitor monitor) throws TeamException {
- ResourceVariantByteStore cache = getByteStore();
- byte[] newRemoteBytes = getBytes(local, remote);
- boolean changed;
- if (newRemoteBytes == null) {
- changed = cache.deleteBytes(local);
- } else {
- changed = cache.setBytes(local, newRemoteBytes);
- }
- if (changed) {
- changedResources.add(local);
- }
- if (depth == IResource.DEPTH_ZERO) return;
- Map children = mergedMembers(local, remote, monitor);
- for (Iterator it = children.keySet().iterator(); it.hasNext();) {
- IResource localChild = (IResource) it.next();
- IResourceVariant remoteChild = (IResourceVariant)children.get(localChild);
- collectChanges(localChild, remoteChild, changedResources,
- depth == IResource.DEPTH_INFINITE ? IResource.DEPTH_INFINITE : IResource.DEPTH_ZERO,
- monitor);
- }
-
- removeStaleBytes(local, children, changedResources);
- }
-
- private void removeStaleBytes(IResource local, Map children, Collection changedResources) throws TeamException {
+ protected IResource[] collectedMembers(IResource local, IResource[] members) throws TeamException {
// Look for resources that have sync bytes but are not in the resources we care about
- ResourceVariantByteStore cache = getByteStore();
- IResource[] resources = getChildrenWithBytes(local);
+ IResource[] resources = getStoredMembers(local);
+ List children = new ArrayList();
+ List changedResources = new ArrayList();
+ children.addAll(Arrays.asList(members));
for (int i = 0; i < resources.length; i++) {
IResource resource = resources[i];
- if (!children.containsKey(resource)) {
+ if (!children.contains(resource)) {
// These sync bytes are stale. Purge them
- cache.flushBytes(resource, IResource.DEPTH_INFINITE);
+ flushVariants(resource, IResource.DEPTH_INFINITE);
changedResources.add(resource);
}
}
+ return (IResource[]) changedResources.toArray(new IResource[changedResources.size()]);
}
-
- /*
- * Return all the children of the local resource, including phantoms, that have bytes
- * associated with them in the resource varant tree of this operation.
- * @param local the local resource
- * @return all children that have bytes stored in the tree.
+
+ /**
+ * Flush any variants for the given resource to the depth specified
+ * @param resource the local resource
+ * @param depth the depth of the flush
* @throws TeamException
*/
- private IResource[] getChildrenWithBytes(IResource local) throws TeamException {
+ private void flushVariants(IResource resource, int depth) throws TeamException {
+ getByteStore().flushBytes(resource, depth);
+ }
+
+ /**
+ * Return all the members of that have resource variant information associated with them,
+ * such as members that are explicitly flagged as not having a resource variant. This list
+ * is used by the collection algorithm to flush variants for which there is no local and
+ * no remote.
+ * @param local the locla resource
+ * @return the local children that have resource variant information cached
+ * @throws TeamException
+ */
+ private IResource[] getStoredMembers(IResource local) throws TeamException {
try {
if (local.getType() != IResource.FILE && (local.exists() || local.isPhantom())) {
// TODO: Not very generic!
@@ -252,92 +128,18 @@ public abstract class ResourceVariantTree implements IResourceVariantTree {
return new IResource[0];
}
- private Map mergedMembers(IResource local, IResourceVariant remote, IProgressMonitor progress) throws TeamException {
-
- // {IResource -> IResourceVariant}
- Map mergedResources = new HashMap();
-
- IResourceVariant[] remoteChildren;
- if (remote == null) {
- remoteChildren = new IResourceVariant[0];
- } else {
- remoteChildren = fetchMembers(remote, progress);
- }
-
-
- IResource[] localChildren = members(local);
-
- if (remoteChildren.length > 0 || localChildren.length > 0) {
- Set allSet = new HashSet(20);
- Map localSet = null;
- Map remoteSet = null;
-
- if (localChildren.length > 0) {
- localSet = new HashMap(10);
- for (int i = 0; i < localChildren.length; i++) {
- IResource localChild = localChildren[i];
- String name = localChild.getName();
- localSet.put(name, localChild);
- allSet.add(name);
- }
- }
-
- if (remoteChildren.length > 0) {
- remoteSet = new HashMap(10);
- for (int i = 0; i < remoteChildren.length; i++) {
- IResourceVariant remoteChild = remoteChildren[i];
- String name = remoteChild.getName();
- remoteSet.put(name, remoteChild);
- allSet.add(name);
- }
- }
-
- Iterator e = allSet.iterator();
- while (e.hasNext()) {
- String keyChildName = (String) e.next();
-
- if (progress != null) {
- if (progress.isCanceled()) {
- throw new OperationCanceledException();
- }
- // XXX show some progress?
- }
-
- IResource localChild =
- localSet != null ? (IResource) localSet.get(keyChildName) : null;
-
- IResourceVariant remoteChild =
- remoteSet != null ? (IResourceVariant) remoteSet.get(keyChildName) : null;
-
- if (localChild == null) {
- // there has to be a remote resource available if we got this far
- Assert.isTrue(remoteChild != null);
- boolean isContainer = remoteChild.isContainer();
- localChild = getResourceChild(local /* parent */, keyChildName, isContainer);
- }
- mergedResources.put(localChild, remoteChild);
- }
- }
- return mergedResources;
- }
+ /**
+ * Get the byte store that is used to cache the serialization bytes
+ * for the resource variants of this tree. A byte store is used
+ * to reduce the memory footprint of the tree.
+ * @return the resource variant tree that is being refreshed.
+ */
+ protected abstract ResourceVariantByteStore getByteStore();
- /*
- * Create a local resource handle for a resource variant whose
- * corresponding local resource was not previously a member of the tree.
- * The resource may or may not exist locally.
- * @param parent the local parent
- * @param childName the name of the local resource
- * @param isContainer the type of resource (file or folder)
- * @return a local resource handle
+ /**
+ * @param project
*/
- private IResource getResourceChild(IResource parent, String childName, boolean isContainer) {
- if (parent.getType() == IResource.FILE) {
- return null;
- }
- if (isContainer) {
- return ((IContainer) parent).getFolder(new Path(childName));
- } else {
- return ((IContainer) parent).getFile(new Path(childName));
- }
+ public void removeRoot(IResource resource) throws TeamException {
+ getByteStore().flushBytes(resource, IResource.DEPTH_INFINITE);
}
}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSCompareSubscriber.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSCompareSubscriber.java
index 13e804052..ae44bfb18 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSCompareSubscriber.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSCompareSubscriber.java
@@ -14,13 +14,16 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.subscribers.ISubscriberChangeEvent;
import org.eclipse.team.core.subscribers.ISubscriberChangeListener;
import org.eclipse.team.core.subscribers.SubscriberChangeEvent;
-import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore;
+import org.eclipse.team.internal.ccvs.core.syncinfo.CVSResourceVariantTree;
+import org.eclipse.team.internal.ccvs.core.syncinfo.MultiTagResourceVariantTree;
+import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree;
import org.eclipse.team.internal.core.subscribers.caches.SessionResourceVariantByteStore;
/**
@@ -32,51 +35,44 @@ public class CVSCompareSubscriber extends CVSSyncTreeSubscriber implements ISubs
public static final String QUALIFIED_NAME = CVSProviderPlugin.ID + ".compare"; //$NON-NLS-1$
private static final String UNIQUE_ID_PREFIX = "compare-"; //$NON-NLS-1$
- private CVSTag tag;
- private SessionResourceVariantByteStore remoteByteStore;
private IResource[] resources;
+ private CVSResourceVariantTree tree;
public CVSCompareSubscriber(IResource[] resources, CVSTag tag) {
super(getUniqueId(), Policy.bind("CVSCompareSubscriber.2", tag.getName()), Policy.bind("CVSCompareSubscriber.3")); //$NON-NLS-1$ //$NON-NLS-2$
this.resources = resources;
- this.tag = tag;
+ tree = new CVSResourceVariantTree(new SessionResourceVariantByteStore(), tag, getCacheFileContentsHint());
+ initialize();
+ }
+
+ public CVSCompareSubscriber(IProject[] projects, CVSTag[] tags, String name) {
+ super(getUniqueId(), Policy.bind("CVSCompareSubscriber.2", name), Policy.bind("CVSCompareSubscriber.3")); //$NON-NLS-1$ //$NON-NLS-2$
+ this.resources = projects;
+ MultiTagResourceVariantTree multiTree = new MultiTagResourceVariantTree(new SessionResourceVariantByteStore(), getCacheFileContentsHint());
+ for (int i = 0; i < tags.length; i++) {
+ multiTree.addProject(projects[i], tags[i]);
+ }
initialize();
}
private void initialize() {
- remoteByteStore = new SessionResourceVariantByteStore();
CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().addListener(this);
}
public void dispose() {
CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().removeListener(this);
- remoteByteStore.dispose();
+ tree.dispose();
}
private static QualifiedName getUniqueId() {
String uniqueId = Long.toString(System.currentTimeMillis());
return new QualifiedName(QUALIFIED_NAME, UNIQUE_ID_PREFIX + uniqueId); //$NON-NLS-1$
}
-
- /* (non-Javadoc)
- * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getRemoteTag()
- */
- protected CVSTag getRemoteTag() {
- return tag;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getBaseTag()
- */
- protected CVSTag getBaseTag() {
- // No base tag needed since it's a two way compare
- return null;
- }
/* (non-Javadoc)
* @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getBaseSynchronizationCache()
*/
- protected ResourceVariantByteStore getBaseSynchronizationCache() {
+ protected ResourceVariantTree getBaseTree() {
// No base cache needed since it's a two way compare
return null;
}
@@ -84,8 +80,8 @@ public class CVSCompareSubscriber extends CVSSyncTreeSubscriber implements ISubs
/* (non-Javadoc)
* @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getRemoteSynchronizationCache()
*/
- protected ResourceVariantByteStore getRemoteSynchronizationCache() {
- return remoteByteStore;
+ protected ResourceVariantTree getRemoteTree() {
+ return tree;
}
/* (non-Javadoc)
@@ -136,6 +132,11 @@ public class CVSCompareSubscriber extends CVSSyncTreeSubscriber implements ISubs
if (removedRoot.getFullPath().isPrefixOf(root.getFullPath())) {
// The root is no longer managed by CVS
removals.add(root);
+ try {
+ tree.removeRoot(root);
+ } catch (TeamException e) {
+ CVSProviderPlugin.log(e);
+ }
}
}
if (removals.isEmpty()) {
@@ -161,7 +162,7 @@ public class CVSCompareSubscriber extends CVSSyncTreeSubscriber implements ISubs
*/
public boolean isSupervised(IResource resource) throws TeamException {
if (super.isSupervised(resource)) {
- if (!resource.exists() && getRemoteSynchronizationCache().getBytes(resource) == null) {
+ if (!resource.exists() && !getRemoteTree().hasResourceVariant(resource)) {
// Exclude conflicting deletions
return false;
}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSMergeSubscriber.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSMergeSubscriber.java
index 500ce8d47..6a38ff1c1 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSMergeSubscriber.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSMergeSubscriber.java
@@ -10,21 +10,36 @@
*******************************************************************************/
package org.eclipse.team.internal.ccvs.core;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
-import org.eclipse.core.resources.*;
-import org.eclipse.core.runtime.*;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.core.TeamException;
-import org.eclipse.team.core.subscribers.*;
-import org.eclipse.team.core.synchronize.*;
+import org.eclipse.team.core.subscribers.ISubscriberChangeEvent;
+import org.eclipse.team.core.subscribers.ISubscriberChangeListener;
+import org.eclipse.team.core.subscribers.SubscriberChangeEvent;
+import org.eclipse.team.core.synchronize.IResourceVariant;
+import org.eclipse.team.core.synchronize.SyncInfo;
+import org.eclipse.team.core.synchronize.SyncInfoFilter;
import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
import org.eclipse.team.internal.ccvs.core.resources.RemoteFile;
-import org.eclipse.team.internal.ccvs.core.syncinfo.CVSSynchronizationCache;
+import org.eclipse.team.internal.ccvs.core.syncinfo.CVSResourceVariantTree;
import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
import org.eclipse.team.internal.ccvs.core.util.Util;
-import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore;
import org.eclipse.team.internal.core.subscribers.caches.PersistantResourceVariantByteStore;
+import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree;
/**
* A CVSMergeSubscriber is responsible for maintaining the remote trees for a merge into
@@ -48,9 +63,8 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour
private CVSTag start, end;
private List roots;
- private CVSSynchronizationCache remoteSynchronizer;
private PersistantResourceVariantByteStore mergedSynchronizer;
- private CVSSynchronizationCache baseSynchronizer;
+ private CVSResourceVariantTree baseTree, remoteTree;
public CVSMergeSubscriber(IResource[] roots, CVSTag start, CVSTag end) {
this(getUniqueId(), roots, start, end);
@@ -75,8 +89,10 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour
private void initialize() {
QualifiedName id = getId();
String syncKeyPrefix = id.getLocalName();
- remoteSynchronizer = new CVSSynchronizationCache(new QualifiedName(SYNC_KEY_QUALIFIER, syncKeyPrefix + end.getName()));
- baseSynchronizer = new CVSSynchronizationCache(new QualifiedName(SYNC_KEY_QUALIFIER, syncKeyPrefix + start.getName()));
+ PersistantResourceVariantByteStore remoteSynchronizer = new PersistantResourceVariantByteStore(new QualifiedName(SYNC_KEY_QUALIFIER, syncKeyPrefix + end.getName()));
+ remoteTree = new CVSResourceVariantTree(remoteSynchronizer, getRemoteTag(), getCacheFileContentsHint());
+ PersistantResourceVariantByteStore baseSynchronizer = new PersistantResourceVariantByteStore(new QualifiedName(SYNC_KEY_QUALIFIER, syncKeyPrefix + start.getName()));
+ baseTree = new CVSResourceVariantTree(baseSynchronizer, getBaseTag(), getCacheFileContentsHint());
mergedSynchronizer = new PersistantResourceVariantByteStore(new QualifiedName(SYNC_KEY_QUALIFIER, syncKeyPrefix + "0merged")); //$NON-NLS-1$
ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
@@ -98,7 +114,7 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour
}
private void internalMerged(IResource resource) throws TeamException {
- byte[] remoteBytes = remoteSynchronizer.getBytes(resource);
+ byte[] remoteBytes = getRemoteByteStore().getBytes(resource);
if (remoteBytes == null) {
mergedSynchronizer.deleteBytes(resource);
} else {
@@ -111,8 +127,8 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour
*/
public void cancel() {
ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
- remoteSynchronizer.dispose();
- baseSynchronizer.dispose();
+ remoteTree.dispose();
+ baseTree.dispose();
mergedSynchronizer.dispose();
}
@@ -127,7 +143,7 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour
* @see org.eclipse.team.core.sync.TeamSubscriber#isSupervised(org.eclipse.core.resources.IResource)
*/
public boolean isSupervised(IResource resource) throws TeamException {
- return getBaseSynchronizationCache().getBytes(resource) != null || getRemoteSynchronizationCache().getBytes(resource) != null;
+ return getBaseTree().hasResourceVariant(resource) || getRemoteTree().hasResourceVariant(resource);
}
public CVSTag getStartTag() {
@@ -192,11 +208,11 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour
*/
public boolean isMerged(IResource resource) throws TeamException {
byte[] mergedBytes = mergedSynchronizer.getBytes(resource);
- byte[] remoteBytes = remoteSynchronizer.getBytes(resource);
+ byte[] remoteBytes = getRemoteByteStore().getBytes(resource);
if (mergedBytes == null) {
return (remoteBytes == null
&& mergedSynchronizer.isVariantKnown(resource)
- && remoteSynchronizer.isVariantKnown(resource));
+ && getRemoteByteStore().isVariantKnown(resource));
}
return Util.equals(mergedBytes, remoteBytes);
}
@@ -238,15 +254,15 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour
/* (non-Javadoc)
* @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getBaseSynchronizationCache()
*/
- protected ResourceVariantByteStore getBaseSynchronizationCache() {
- return baseSynchronizer;
+ protected ResourceVariantTree getBaseTree() {
+ return baseTree;
}
/* (non-Javadoc)
* @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getRemoteSynchronizationCache()
*/
- protected ResourceVariantByteStore getRemoteSynchronizationCache() {
- return remoteSynchronizer;
+ protected ResourceVariantTree getRemoteTree() {
+ return remoteTree;
}
protected boolean getCacheFileContentsHint() {
@@ -261,7 +277,7 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour
List unrefreshed = new ArrayList();
for (int i = 0; i < resources.length; i++) {
IResource resource = resources[i];
- if (!baseSynchronizer.isVariantKnown(resource)) {
+ if (!getBaseByteStore().isVariantKnown(resource)) {
unrefreshed.add(resource);
}
}
@@ -301,7 +317,7 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour
if (resource.getType() == IResource.FILE) {
ICVSFile local = CVSWorkspaceRoot.getCVSFileFor((IFile)resource);
byte[] localBytes = local.getSyncBytes();
- byte[] remoteBytes = remoteSynchronizer.getBytes(resource);
+ byte[] remoteBytes = getRemoteByteStore().getBytes(resource);
if (remoteBytes != null
&& localBytes != null
&& local.exists()
@@ -322,7 +338,7 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour
// Use the merged bytes for the base if there are some
byte[] mergedBytes = mergedSynchronizer.getBytes(resource);
if (mergedBytes != null) {
- byte[] parentBytes = baseSynchronizer.getBytes(resource.getParent());
+ byte[] parentBytes = getBaseByteStore().getBytes(resource.getParent());
if (parentBytes != null) {
return RemoteFile.fromBytes(resource, mergedBytes, parentBytes);
}
@@ -334,4 +350,18 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour
}
return super.getBaseResource(resource);
}
+
+ /*
+ * TODO: Should not need to access this here
+ */
+ private PersistantResourceVariantByteStore getRemoteByteStore() {
+ return (PersistantResourceVariantByteStore)((CVSResourceVariantTree)getRemoteTree()).getByteStore();
+ }
+
+ /*
+ * TODO: Should not need to access this here
+ */
+ private PersistantResourceVariantByteStore getBaseByteStore() {
+ return (PersistantResourceVariantByteStore)((CVSResourceVariantTree)getBaseTree()).getByteStore();
+ }
} \ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSSyncTreeSubscriber.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSSyncTreeSubscriber.java
index 4bc1dca7b..fe1865d48 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSSyncTreeSubscriber.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSSyncTreeSubscriber.java
@@ -10,17 +10,33 @@
*******************************************************************************/
package org.eclipse.team.internal.ccvs.core;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
-import org.eclipse.core.resources.*;
-import org.eclipse.core.runtime.*;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceStatus;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.Status;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.core.TeamException;
-import org.eclipse.team.core.subscribers.*;
-import org.eclipse.team.core.synchronize.*;
-import org.eclipse.team.internal.core.subscribers.caches.*;
-import org.eclipse.team.internal.ccvs.core.resources.*;
-import org.eclipse.team.internal.ccvs.core.syncinfo.*;
+import org.eclipse.team.core.subscribers.SubscriberChangeEvent;
+import org.eclipse.team.core.synchronize.IResourceVariant;
+import org.eclipse.team.core.synchronize.IResourceVariantComparator;
+import org.eclipse.team.core.synchronize.SyncInfo;
+import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
+import org.eclipse.team.internal.core.subscribers.caches.PersistantResourceVariantByteStore;
+import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore;
+import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree;
+import org.eclipse.team.internal.core.subscribers.caches.SyncTreeSubscriber;
/**
* This class provides common funtionality for three way sychronizing
@@ -151,28 +167,16 @@ public abstract class CVSSyncTreeSubscriber extends SyncTreeSubscriber {
protected IResource[] refreshBase(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException {
if (isThreeWay()) {
- return new CVSRefreshOperation(getBaseSynchronizationCache(), null, getBaseTag(), getCacheFileContentsHint())
- .refresh(resources, depth, monitor);
+ return getBaseTree().refresh(resources, depth, monitor);
} else {
return new IResource[0];
}
}
protected IResource[] refreshRemote(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException {
- return new CVSRefreshOperation(getRemoteSynchronizationCache(), getBaseSynchronizationCache(), getRemoteTag(), getCacheFileContentsHint())
- .refresh(resources, depth, monitor);
+ return getRemoteTree().refresh(resources, depth, monitor);
}
- /**
- * Return the tag associated with the base tree. t is used by the refreshBase method.
- */
- protected abstract CVSTag getRemoteTag();
-
- /**
- * Return the tag associated with the base tree. t is used by the refreshRemote method.
- */
- protected abstract CVSTag getBaseTag();
-
/* (non-Javadoc)
* @see org.eclipse.team.core.sync.ISyncTreeSubscriber#isSupervised(org.eclipse.core.resources.IResource)
*/
@@ -199,66 +203,26 @@ public abstract class CVSSyncTreeSubscriber extends SyncTreeSubscriber {
}
public IResourceVariant getRemoteResource(IResource resource) throws TeamException {
- return getRemoteResource(resource, getRemoteSynchronizationCache());
+ return getRemoteTree().getResourceVariant(resource);
}
public IResourceVariant getBaseResource(IResource resource) throws TeamException {
if (isThreeWay()) {
- return getRemoteResource(resource, getBaseSynchronizationCache());
+ return getBaseTree().getResourceVariant(resource);
} else {
return null;
}
}
/**
- * Return the synchronization cache that provides access to the base sychronization bytes.
+ * Return the base resource variant tree.
*/
- protected abstract ResourceVariantByteStore getBaseSynchronizationCache();
+ protected abstract ResourceVariantTree getBaseTree();
/**
- * Return the synchronization cache that provides access to the base sychronization bytes.
+ * Return the remote resource variant tree.
*/
- protected abstract ResourceVariantByteStore getRemoteSynchronizationCache();
-
- public IResourceVariant getRemoteResource(IResource resource, ResourceVariantByteStore cache) throws TeamException {
- byte[] remoteBytes = cache.getBytes(resource);
- if (remoteBytes == null) {
- // There is no remote handle for this resource
- return null;
- } else {
- // TODO: This code assumes that the type of the remote resource
- // matches that of the local resource. This may not be true.
- if (resource.getType() == IResource.FILE) {
- byte[] parentBytes = cache.getBytes(resource.getParent());
- if (parentBytes == null) {
- // Before failing, try and use the local folder sync bytes
- ICVSFolder local = CVSWorkspaceRoot.getCVSFolderFor(resource.getParent());
- FolderSyncInfo info = local.getFolderSyncInfo();
- if (info == null) {
- CVSProviderPlugin.log(new CVSException(
- Policy.bind("ResourceSynchronizer.missingParentBytesOnGet", getSyncName(cache).toString(), resource.getFullPath().toString()))); //$NON-NLS-1$
- // Assume there is no remote and the problem is a programming error
- return null;
- } else {
- // Use the folder sync from the workspace and the tag from the file
-
- byte[] tagBytes = ResourceSyncInfo.getTagBytes(remoteBytes);
- CVSTag tag;
- if (tagBytes == null || tagBytes.length == 0) {
- tag = CVSTag.DEFAULT;
- } else {
- tag = new CVSEntryLineTag(new String(tagBytes));
- }
- FolderSyncInfo newInfo = new FolderSyncInfo(info.getRepository(), info.getRoot(), tag, false);
- parentBytes = newInfo.getBytes();
- }
- }
- return RemoteFile.fromBytes(resource, remoteBytes, parentBytes);
- } else {
- return RemoteFolder.fromBytes(resource, remoteBytes);
- }
- }
- }
+ protected abstract ResourceVariantTree getRemoteTree();
private String getSyncName(ResourceVariantByteStore cache) {
if (cache instanceof PersistantResourceVariantByteStore) {
@@ -271,7 +235,7 @@ public abstract class CVSSyncTreeSubscriber extends SyncTreeSubscriber {
* @see org.eclipse.team.core.subscribers.helpers.SyncTreeSubscriber#hasRemote(org.eclipse.core.resources.IResource)
*/
protected boolean hasRemote(IResource resource) throws TeamException {
- return getRemoteSynchronizationCache().getBytes(resource) != null;
+ return getRemoteTree().hasResourceVariant(resource);
}
/* (non-Javadoc)
@@ -296,9 +260,9 @@ public abstract class CVSSyncTreeSubscriber extends SyncTreeSubscriber {
throw e;
}
}
- allMembers.addAll(Arrays.asList(getMembers(getRemoteSynchronizationCache(), resource)));
+ allMembers.addAll(Arrays.asList(getMembers(getRemoteTree(), resource)));
if (isThreeWay()) {
- allMembers.addAll(Arrays.asList(getMembers(getBaseSynchronizationCache(), resource)));
+ allMembers.addAll(Arrays.asList(getMembers(getBaseTree(), resource)));
}
for (Iterator iterator = allMembers.iterator(); iterator.hasNext();) {
IResource member = (IResource) iterator.next();
@@ -316,11 +280,11 @@ public abstract class CVSSyncTreeSubscriber extends SyncTreeSubscriber {
}
}
- private IResource[] getMembers(ResourceVariantByteStore cache, IResource resource) throws TeamException, CoreException {
+ private IResource[] getMembers(ResourceVariantTree tree, IResource resource) throws TeamException, CoreException {
// Filter and return only phantoms associated with the remote synchronizer.
IResource[] members;
try {
- members = cache.members(resource);
+ members = tree.members(resource);
} catch (CoreException e) {
if (!isSupervised(resource) || e.getStatus().getCode() == IResourceStatus.RESOURCE_NOT_FOUND) {
// The resource is no longer supervised or doesn't exist in any form
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSWorkspaceSubscriber.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSWorkspaceSubscriber.java
index 3fb66fe63..83c67a659 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSWorkspaceSubscriber.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSWorkspaceSubscriber.java
@@ -13,8 +13,16 @@ package org.eclipse.team.internal.ccvs.core;
import java.util.ArrayList;
import java.util.List;
-import org.eclipse.core.resources.*;
-import org.eclipse.core.runtime.*;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.subscribers.ISubscriberChangeEvent;
@@ -23,19 +31,22 @@ import org.eclipse.team.core.synchronize.IResourceVariant;
import org.eclipse.team.core.synchronize.SyncInfo;
import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer;
-import org.eclipse.team.internal.ccvs.core.syncinfo.*;
+import org.eclipse.team.internal.ccvs.core.syncinfo.CVSBaseResourceVariantTree;
+import org.eclipse.team.internal.ccvs.core.syncinfo.CVSDescendantResourceVariantTree;
+import org.eclipse.team.internal.ccvs.core.syncinfo.CVSResourceVariantTree;
+import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
import org.eclipse.team.internal.ccvs.core.util.ResourceStateChangeListeners;
+import org.eclipse.team.internal.core.subscribers.caches.DescendantResourceVariantByteStore;
import org.eclipse.team.internal.core.subscribers.caches.PersistantResourceVariantByteStore;
import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore;
-import org.eclipse.team.internal.ccvs.core.Policy;
+import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree;
/**
* CVSWorkspaceSubscriber
*/
public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IResourceStateChangeListener {
- private CVSDescendantSynchronizationCache remoteSynchronizer;
- private ResourceVariantByteStore baseSynchronizer;
+ private CVSResourceVariantTree baseTree, remoteTree;
// qualified name for remote sync info
private static final String REMOTE_RESOURCE_KEY = "remote-resource-key"; //$NON-NLS-1$
@@ -44,10 +55,12 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe
super(id, name, description);
// install sync info participant
- baseSynchronizer = new CVSBaseSynchronizationCache();
- remoteSynchronizer = new CVSDescendantSynchronizationCache(
+ ResourceVariantByteStore baseSynchronizer = new CVSBaseResourceVariantTree();
+ baseTree = new CVSResourceVariantTree(baseSynchronizer, getBaseTag(), getCacheFileContentsHint());
+ CVSDescendantResourceVariantTree remoteSynchronizer = new CVSDescendantResourceVariantTree(
baseSynchronizer,
new PersistantResourceVariantByteStore(new QualifiedName(SYNC_KEY_QUALIFIER, REMOTE_RESOURCE_KEY)));
+ remoteTree = new CVSResourceVariantTree(remoteSynchronizer, getRemoteTag(), getCacheFileContentsHint());
ResourceStateChangeListeners.getListener().addResourceStateChangeListener(this);
}
@@ -84,19 +97,20 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe
private void internalResourceSyncInfoChanged(IResource[] changedResources, boolean canModifyWorkspace) {
// IMPORTANT NOTE: This will throw exceptions if performed during the POST_CHANGE delta phase!!!
+ DescendantResourceVariantByteStore remoteByteStore = getRemoteByteStore();
for (int i = 0; i < changedResources.length; i++) {
IResource resource = changedResources[i];
try {
if (resource.getType() == IResource.FILE
&& (resource.exists() || resource.isPhantom())) {
- byte[] remoteBytes = remoteSynchronizer.getBytes(resource);
+ byte[] remoteBytes = remoteByteStore.getBytes(resource);
if (remoteBytes == null) {
- if (remoteSynchronizer.isVariantKnown(resource)) {
+ if (remoteByteStore.isVariantKnown(resource)) {
// The remote is known not to exist. If the local resource is
// managed then this information is stale
- if (getBaseSynchronizationCache().getBytes(resource) != null) {
+ if (getBaseTree().hasResourceVariant(resource)) {
if (canModifyWorkspace) {
- remoteSynchronizer.flushBytes(resource, IResource.DEPTH_ZERO);
+ remoteByteStore.flushBytes(resource, IResource.DEPTH_ZERO);
} else {
// The revision comparison will handle the stale sync bytes
// TODO: Unless the remote is known not to exist (see bug 52936)
@@ -104,19 +118,19 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe
}
}
} else {
- byte[] localBytes = baseSynchronizer.getBytes(resource);
+ byte[] localBytes = getBaseByteStore().getBytes(resource);
if (localBytes == null || !isLaterRevision(remoteBytes, localBytes)) {
if (canModifyWorkspace) {
- remoteSynchronizer.flushBytes(resource, IResource.DEPTH_ZERO);
+ remoteByteStore.flushBytes(resource, IResource.DEPTH_ZERO);
} else {
- // The getRemoteResource method handles the stale sync bytes
+ // The remote byte store handles the stale sync bytes
}
}
}
} else if (resource.getType() == IResource.FOLDER) {
// If the base has sync info for the folder, purge the remote bytes
- if (getBaseSynchronizationCache().getBytes(resource) != null && canModifyWorkspace) {
- remoteSynchronizer.flushBytes(resource, IResource.DEPTH_ZERO);
+ if (getBaseTree().hasResourceVariant(resource) && canModifyWorkspace) {
+ remoteByteStore.flushBytes(resource, IResource.DEPTH_ZERO);
}
}
} catch (TeamException e) {
@@ -168,7 +182,7 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe
*/
public void projectDeconfigured(IProject project) {
try {
- remoteSynchronizer.flushBytes(project, IResource.DEPTH_INFINITE);
+ getRemoteTree().removeRoot(project);
} catch (TeamException e) {
CVSProviderPlugin.log(e);
}
@@ -179,7 +193,7 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe
public void setRemote(IProject project, IResourceVariant remote, IProgressMonitor monitor) throws TeamException {
// TODO: This exposes internal behavior to much
IResource[] changedResources =
- new CVSRefreshOperation(remoteSynchronizer, baseSynchronizer, null, false).collectChanges(project, remote, IResource.DEPTH_INFINITE, monitor);
+ ((CVSResourceVariantTree)getRemoteTree()).collectChanges(project, remote, IResource.DEPTH_INFINITE, monitor);
if (changedResources.length != 0) {
fireTeamResourceChange(SubscriberChangeEvent.asSyncChangedDeltas(this, changedResources));
}
@@ -212,15 +226,15 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe
/* (non-Javadoc)
* @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getBaseSynchronizationCache()
*/
- protected ResourceVariantByteStore getBaseSynchronizationCache() {
- return baseSynchronizer;
+ protected ResourceVariantTree getBaseTree() {
+ return baseTree;
}
/* (non-Javadoc)
* @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getRemoteSynchronizationCache()
*/
- protected ResourceVariantByteStore getRemoteSynchronizationCache() {
- return remoteSynchronizer;
+ protected ResourceVariantTree getRemoteTree() {
+ return remoteTree;
}
/* (non-Javadoc)
@@ -271,7 +285,7 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe
}
private boolean hasIncomingChange(IResource resource) throws TeamException {
- return remoteSynchronizer.isVariantKnown(resource);
+ return getRemoteByteStore().isVariantKnown(resource);
}
private boolean hasOutgoingChange(IResource resource, IProgressMonitor monitor) throws CVSException {
@@ -294,5 +308,18 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe
return !folder.isCVSFolder() && !folder.isIgnored();
}
}
+
+ /*
+ * TODO: Should not need to access this here
+ */
+ private CVSDescendantResourceVariantTree getRemoteByteStore() {
+ return (CVSDescendantResourceVariantTree)((CVSResourceVariantTree)getRemoteTree()).getByteStore();
+ }
+ /*
+ * TODO: Should not need to access this here
+ */
+ private ResourceVariantByteStore getBaseByteStore() {
+ return ((CVSResourceVariantTree)getBaseTree()).getByteStore();
+ }
}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSBaseSynchronizationCache.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSBaseResourceVariantTree.java
index b1c615668..0484285cc 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSBaseSynchronizationCache.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSBaseResourceVariantTree.java
@@ -17,7 +17,7 @@ import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStor
import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer;
-public class CVSBaseSynchronizationCache extends ResourceVariantByteStore {
+public class CVSBaseResourceVariantTree extends ResourceVariantByteStore {
public void dispose() {
// Do nothing
}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSDescendantSynchronizationCache.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSDescendantResourceVariantTree.java
index 7baefb8cc..3cc2ae128 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSDescendantSynchronizationCache.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSDescendantResourceVariantTree.java
@@ -18,9 +18,9 @@ import org.eclipse.team.internal.ccvs.core.*;
/**
* CVS sycnrhonization cache that ignores stale remote bytes
*/
-public class CVSDescendantSynchronizationCache extends DescendantResourceVariantByteStore {
+public class CVSDescendantResourceVariantTree extends DescendantResourceVariantByteStore {
- public CVSDescendantSynchronizationCache(ResourceVariantByteStore baseCache, PersistantResourceVariantByteStore remoteCache) {
+ public CVSDescendantResourceVariantTree(ResourceVariantByteStore baseCache, PersistantResourceVariantByteStore remoteCache) {
super(baseCache, remoteCache);
}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSRefreshOperation.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSRefreshOperation.java
deleted file mode 100644
index 829a34dd6..000000000
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSRefreshOperation.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2003 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.team.internal.ccvs.core.syncinfo;
-
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.team.core.TeamException;
-import org.eclipse.team.core.synchronize.IResourceVariant;
-import org.eclipse.team.internal.ccvs.core.*;
-import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
-import org.eclipse.team.internal.ccvs.core.resources.RemoteResource;
-import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore;
-import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree;
-
-/**
- * CVS Specific refresh operation
- */
-public class CVSRefreshOperation extends ResourceVariantTree {
-
- private ResourceVariantByteStore cache, baseCache;
- private CVSTag tag;
- private boolean cacheFileContentsHint;
- private CVSSyncTreeSubscriber subscriber;
-
- public CVSRefreshOperation(ResourceVariantByteStore cache, ResourceVariantByteStore baseCache, CVSTag tag, boolean cacheFileContentsHint) {
- this.tag = tag;
- this.cache = cache;
- this.baseCache = cache;
- this.cacheFileContentsHint = cacheFileContentsHint;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.team.core.subscribers.RefreshOperation#getSynchronizationCache()
- */
- protected ResourceVariantByteStore getByteStore() {
- return cache;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.team.core.subscribers.RefreshOperation#getRemoteSyncBytes(org.eclipse.core.resources.IResource, org.eclipse.team.core.subscribers.ISubscriberResource)
- */
- protected byte[] getBytes(IResource local, IResourceVariant remote) throws TeamException {
- if (remote != null) {
- return ((RemoteResource)remote).getSyncBytes();
- } else {
- if (local.getType() == IResource.FOLDER && baseCache != null) {
- // If there is no remote, use the local sync for the folder
- return baseCache.getBytes(local);
- }
- return null;
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.team.core.subscribers.RefreshOperation#getRemoteChildren(org.eclipse.team.core.subscribers.ISubscriberResource, org.eclipse.core.runtime.IProgressMonitor)
- */
- protected IResourceVariant[] fetchMembers(IResourceVariant remote, IProgressMonitor progress) throws TeamException {
- ICVSRemoteResource[] children = remote != null ? (ICVSRemoteResource[])((RemoteResource)remote).members(progress) : new ICVSRemoteResource[0];
- IResourceVariant[] result = new IResourceVariant[children.length];
- for (int i = 0; i < children.length; i++) {
- result[i] = (IResourceVariant)children[i];
- }
- return result;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.team.core.subscribers.RefreshOperation#buildRemoteTree(org.eclipse.core.resources.IResource, int, boolean, org.eclipse.core.runtime.IProgressMonitor)
- */
- protected IResourceVariant fetchVariant(IResource resource, int depth, IProgressMonitor monitor) throws TeamException {
- // TODO: we are currently ignoring the depth parameter because the build remote tree is
- // by default deep!
- return (IResourceVariant)CVSWorkspaceRoot.getRemoteTree(resource, tag, cacheFileContentsHint, monitor);
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTreeRefreshOperation#collectChanges(org.eclipse.core.resources.IResource, org.eclipse.team.core.synchronize.IResourceVariant, int, org.eclipse.core.runtime.IProgressMonitor)
- */
- public IResource[] collectChanges(IResource local,
- IResourceVariant remote, int depth, IProgressMonitor monitor)
- throws TeamException {
- return super.collectChanges(local, remote, depth, monitor);
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.team.internal.core.subscribers.caches.IResourceVariantTree#getRoots()
- */
- public IResource[] getRoots() {
- return subscriber.roots();
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.team.internal.core.subscribers.caches.IResourceVariantTree#getResourceVariant(org.eclipse.core.resources.IResource)
- */
- public IResourceVariant getResourceVariant(IResource resource) throws TeamException {
- return subscriber.getRemoteResource(resource, getByteStore());
- }
-
-}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSResourceVariantTree.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSResourceVariantTree.java
new file mode 100644
index 000000000..f9803c0c9
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSResourceVariantTree.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.internal.ccvs.core.syncinfo;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.team.core.RepositoryProvider;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.synchronize.IResourceVariant;
+import org.eclipse.team.internal.ccvs.core.CVSException;
+import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
+import org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber;
+import org.eclipse.team.internal.ccvs.core.CVSTag;
+import org.eclipse.team.internal.ccvs.core.ICVSFolder;
+import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource;
+import org.eclipse.team.internal.ccvs.core.Policy;
+import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
+import org.eclipse.team.internal.ccvs.core.resources.RemoteFile;
+import org.eclipse.team.internal.ccvs.core.resources.RemoteFolder;
+import org.eclipse.team.internal.ccvs.core.resources.RemoteResource;
+import org.eclipse.team.internal.core.subscribers.caches.PersistantResourceVariantByteStore;
+import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore;
+import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree;
+
+/**
+ * CVS Specific refresh operation
+ */
+public class CVSResourceVariantTree extends ResourceVariantTree {
+
+ private ResourceVariantByteStore cache;
+ private CVSTag tag;
+ private boolean cacheFileContentsHint;
+ private CVSSyncTreeSubscriber subscriber;
+
+ public CVSResourceVariantTree(ResourceVariantByteStore cache, CVSTag tag, boolean cacheFileContentsHint) {
+ this.tag = tag;
+ this.cache = cache;
+ this.cacheFileContentsHint = cacheFileContentsHint;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.team.core.subscribers.RefreshOperation#getSynchronizationCache()
+ */
+ public ResourceVariantByteStore getByteStore() {
+ return cache;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.team.core.subscribers.RefreshOperation#getRemoteSyncBytes(org.eclipse.core.resources.IResource, org.eclipse.team.core.subscribers.ISubscriberResource)
+ */
+ protected byte[] getBytes(IResource local, IResourceVariant remote) throws TeamException {
+ if (remote != null) {
+ return ((RemoteResource)remote).getSyncBytes();
+ } else {
+ if (local.getType() == IResource.FOLDER) {
+ // If there is no remote, use the local sync for the folder
+ return getBaseBytes((IContainer)local, getTag(local));
+ }
+ return null;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.team.core.subscribers.RefreshOperation#getRemoteChildren(org.eclipse.team.core.subscribers.ISubscriberResource, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ protected IResourceVariant[] fetchMembers(IResourceVariant remote, IProgressMonitor progress) throws TeamException {
+ ICVSRemoteResource[] children = remote != null ? (ICVSRemoteResource[])((RemoteResource)remote).members(progress) : new ICVSRemoteResource[0];
+ IResourceVariant[] result = new IResourceVariant[children.length];
+ for (int i = 0; i < children.length; i++) {
+ result[i] = (IResourceVariant)children[i];
+ }
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.team.core.subscribers.RefreshOperation#buildRemoteTree(org.eclipse.core.resources.IResource, int, boolean, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ protected IResourceVariant fetchVariant(IResource resource, int depth, IProgressMonitor monitor) throws TeamException {
+ // TODO: we are currently ignoring the depth parameter because the build remote tree is
+ // by default deep!
+ return (IResourceVariant)CVSWorkspaceRoot.getRemoteTree(resource, getTag(resource), cacheFileContentsHint, monitor);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTreeRefreshOperation#collectChanges(org.eclipse.core.resources.IResource, org.eclipse.team.core.synchronize.IResourceVariant, int, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public IResource[] collectChanges(IResource local,
+ IResourceVariant remote, int depth, IProgressMonitor monitor)
+ throws TeamException {
+ return super.collectChanges(local, remote, depth, monitor);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.team.internal.core.subscribers.caches.IResourceVariantTree#getRoots()
+ */
+ public IResource[] getRoots() {
+ return subscriber.roots();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.team.internal.core.subscribers.caches.IResourceVariantTree#getResourceVariant(org.eclipse.core.resources.IResource)
+ */
+ public IResourceVariant getResourceVariant(IResource resource) throws TeamException {
+ byte[] remoteBytes = cache.getBytes(resource);
+ if (remoteBytes == null) {
+ // There is no remote handle for this resource
+ return null;
+ } else {
+ if (resource.getType() == IResource.FILE) {
+ byte[] parentBytes = getParentBytes(resource);
+ if (parentBytes == null) {
+ IProject project = resource.getProject();
+ if (project.exists() && RepositoryProvider.getProvider(project, CVSProviderPlugin.getTypeId()) != null) {
+ CVSProviderPlugin.log(new CVSException(
+ Policy.bind("ResourceSynchronizer.missingParentBytesOnGet", getSyncName(cache).toString(), resource.getFullPath().toString()))); //$NON-NLS-1$
+ // Assume there is no remote and the problem is a programming error
+ }
+ return null;
+ }
+ return RemoteFile.fromBytes(resource, remoteBytes, parentBytes);
+ } else {
+ return RemoteFolder.fromBytes(resource, remoteBytes);
+ }
+ }
+ }
+
+ private String getSyncName(ResourceVariantByteStore cache) {
+ if (cache instanceof PersistantResourceVariantByteStore) {
+ return ((PersistantResourceVariantByteStore)cache).getSyncName().toString();
+ }
+ return cache.getClass().getName();
+ }
+
+
+ private byte[] getParentBytes(IResource resource) throws TeamException {
+ IContainer parent = resource.getParent();
+ byte[] bytes = cache.getBytes(parent);
+ if (bytes == null ) {
+ bytes = getBaseBytes(parent, getTag(resource));
+ }
+ return bytes;
+ }
+
+ private byte[] getBaseBytes(IContainer parent, CVSTag tag) throws CVSException {
+ byte[] bytes;
+ // Look locally for the folder bytes
+ ICVSFolder local = CVSWorkspaceRoot.getCVSFolderFor(parent);
+ FolderSyncInfo info = local.getFolderSyncInfo();
+ if (info == null) {
+ bytes = null;
+ } else {
+ // Use the folder sync from the workspace and the tag from the store
+ FolderSyncInfo newInfo = new FolderSyncInfo(info.getRepository(), info.getRoot(), tag, false);
+ bytes = newInfo.getBytes();
+ }
+ return bytes;
+ }
+
+ protected CVSTag getTag(IResource resource) {
+ return tag;
+ }
+
+ /**
+ * Dispose of the underlying byte store
+ */
+ public void dispose() {
+ getByteStore().dispose();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#setVariant(org.eclipse.core.resources.IResource, org.eclipse.team.core.synchronize.IResourceVariant)
+ */
+ protected boolean setVariant(IResource local, IResourceVariant remote) throws TeamException {
+ boolean changed = super.setVariant(local, remote);
+ if (local.getType() == IResource.FILE && getByteStore().getBytes(local) != null && !parentHasSyncBytes(local)) {
+ // Log a warning if there is no sync bytes available for the resource's
+ // parent but there is valid sync bytes for the child
+ CVSProviderPlugin.log(new TeamException(Policy.bind("ResourceSynchronizer.missingParentBytesOnSet", getSyncName(getByteStore()), local.getFullPath().toString()))); //$NON-NLS-1$
+ }
+ return changed;
+ }
+
+ private boolean parentHasSyncBytes(IResource resource) throws TeamException {
+ if (resource.getType() == IResource.PROJECT) return true;
+ return getParentBytes(resource) != null;
+ }
+}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSSynchronizationCache.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSSynchronizationCache.java
deleted file mode 100644
index 32579df08..000000000
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSSynchronizationCache.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2003 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.team.internal.ccvs.core.syncinfo;
-
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.QualifiedName;
-import org.eclipse.team.core.TeamException;
-import org.eclipse.team.internal.core.subscribers.caches.PersistantResourceVariantByteStore;
-import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
-import org.eclipse.team.internal.ccvs.core.Policy;
-
-/**
- * Override <code>PersistantResourceVariantByteStore</code> to log an error
- * if there are no parent bytes for a file.
- */
-public class CVSSynchronizationCache extends PersistantResourceVariantByteStore {
-
- public CVSSynchronizationCache(QualifiedName name) {
- super(name);
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.team.core.subscribers.helpers.SynchronizationCache#setSyncBytes(org.eclipse.core.resources.IResource, byte[])
- */
- public boolean setBytes(IResource resource, byte[] bytes) throws TeamException {
- boolean changed = super.setBytes(resource, bytes);
- if (resource.getType() == IResource.FILE && getBytes(resource) != null && !parentHasSyncBytes(resource)) {
- // Log a warning if there is no sync bytes available for the resource's
- // parent but there is valid sync bytes for the child
- CVSProviderPlugin.log(new TeamException(Policy.bind("ResourceSynchronizer.missingParentBytesOnSet", getSyncName().toString(), resource.getFullPath().toString()))); //$NON-NLS-1$
- }
- return changed;
- }
-
- /**
- * Indicates whether the parent of the given local resource has sync bytes for its
- * corresponding remote resource. The parent bytes of a remote resource are required
- * (by CVS) to create a handle to the remote resource.
- */
- protected boolean parentHasSyncBytes(IResource resource) throws TeamException {
- if (resource.getType() == IResource.PROJECT) return true;
- return (getBytes(resource.getParent()) != null);
- }
-}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/MultiTagResourceVariantTree.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/MultiTagResourceVariantTree.java
new file mode 100644
index 000000000..742d35454
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/MultiTagResourceVariantTree.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.internal.ccvs.core.syncinfo;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.team.internal.ccvs.core.CVSTag;
+import org.eclipse.team.internal.ccvs.core.util.Assert;
+import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore;
+
+/**
+ * A CVS resource variant tree that associates a different tag with each root project.
+ */
+public class MultiTagResourceVariantTree extends CVSResourceVariantTree {
+
+ Map projects = new HashMap();
+
+ public MultiTagResourceVariantTree(ResourceVariantByteStore cache, boolean cacheFileContentsHint) {
+ super(cache, null, cacheFileContentsHint);
+ }
+
+ public void addProject(IProject project, CVSTag tag) {
+ Assert.isNotNull(project);
+ Assert.isNotNull(tag);
+ projects.put(project, tag);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.team.internal.ccvs.core.syncinfo.CVSResourceVariantTree#getTag(org.eclipse.core.resources.IResource)
+ */
+ protected CVSTag getTag(IResource resource) {
+ return (CVSTag)projects.get(resource.getProject());
+ }
+}
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SyncInfoCompareInput.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SyncInfoCompareInput.java
index 3b95a0f5a..03b0ae06a 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SyncInfoCompareInput.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SyncInfoCompareInput.java
@@ -14,7 +14,6 @@ import java.lang.reflect.InvocationTargetException;
import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.CompareEditorInput;
-import org.eclipse.compare.CompareUI;
import org.eclipse.compare.IContentChangeListener;
import org.eclipse.compare.IContentChangeNotifier;
import org.eclipse.compare.ITypedElement;

Back to the top