diff options
author | Michael Valenta | 2004-02-25 20:36:43 +0000 |
---|---|---|
committer | Michael Valenta | 2004-02-25 20:36:43 +0000 |
commit | e20c361fdfa3aa0fcbe688e0cef14c3dc717ee72 (patch) | |
tree | 0ef84a3d9a628b08d6fb45d7db87afcc135fc092 | |
parent | 2e13c8093cc48e9747155b55d64041daf92fcefd (diff) | |
download | eclipse.platform.team-branch_20031205_synchWorkFlowEnhancements.tar.gz eclipse.platform.team-branch_20031205_synchWorkFlowEnhancements.tar.xz eclipse.platform.team-branch_20031205_synchWorkFlowEnhancements.zip |
*** empty log message ***branch_20031205_synchWorkFlowEnhancements
18 files changed, 624 insertions, 558 deletions
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/DescendantResourceVariantTree.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/DescendantResourceVariantByteStore.java index e3653f968..b24be5964 100644 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/DescendantResourceVariantTree.java +++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/DescendantResourceVariantByteStore.java @@ -10,11 +10,14 @@ *******************************************************************************/ package org.eclipse.team.internal.core.subscribers.caches; +import java.util.HashSet; +import java.util.Set; + import org.eclipse.core.resources.IResource; import org.eclipse.team.core.TeamException; /** - * A <code>ResourceVariantTree</code> that optimizes the memory footprint + * A <code>ResourceVariantByteStore</code> that optimizes the memory footprint * of a remote resource variant tree by only storing those bytes that * differ from a base resource variant tree. This class should only be used * for cases where the base and remote are on the same line-of-descent. @@ -29,24 +32,24 @@ import org.eclipse.team.core.TeamException; * from the main trunck to a branch, any cached remote resource variants would be stale. */ -public abstract class DescendantResourceVariantTree extends ResourceVariantTree { - ResourceVariantTree baseCache, remoteCache; +public abstract class DescendantResourceVariantByteStore extends ResourceVariantByteStore { + ResourceVariantByteStore baseCache, remoteCache; - public DescendantResourceVariantTree(ResourceVariantTree baseCache, ResourceVariantTree remoteCache) { + public DescendantResourceVariantByteStore(ResourceVariantByteStore baseCache, ResourceVariantByteStore remoteCache) { this.baseCache = baseCache; this.remoteCache = remoteCache; } /** * This method will dispose the remote cache but not the base cache. - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#dispose() + * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#dispose() */ public void dispose() { remoteCache.dispose(); } /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#getBytes(org.eclipse.core.resources.IResource) + * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#getBytes(org.eclipse.core.resources.IResource) */ public byte[] getBytes(IResource resource) throws TeamException { byte[] remoteBytes = remoteCache.getBytes(resource); @@ -76,31 +79,38 @@ public abstract class DescendantResourceVariantTree extends ResourceVariantTree } /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#setBytes(org.eclipse.core.resources.IResource, byte[]) + * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#setBytes(org.eclipse.core.resources.IResource, byte[]) */ public boolean setBytes(IResource resource, byte[] bytes) throws TeamException { byte[] baseBytes = baseCache.getBytes(resource); if (baseBytes != null && equals(baseBytes, bytes)) { // Remove the existing bytes so the base will be used (thus saving space) - return remoteCache.removeBytes(resource, IResource.DEPTH_ZERO); + return remoteCache.flushBytes(resource, IResource.DEPTH_ZERO); } else { return remoteCache.setBytes(resource, bytes); } } /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#removeBytes(org.eclipse.core.resources.IResource, int) + * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#removeBytes(org.eclipse.core.resources.IResource, int) */ - public boolean removeBytes(IResource resource, int depth) throws TeamException { - return remoteCache.removeBytes(resource, depth); + public boolean flushBytes(IResource resource, int depth) throws TeamException { + return remoteCache.flushBytes(resource, depth); } - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#isVariantKnown(org.eclipse.core.resources.IResource) + /** + * Return <code>true</code> if the variant associated with the given local + * resource has been cached. This method is useful for those cases when + * there are no bytes for a resource variant and the client wants to + * know if this means that the remote does exist (i.e. this method returns + * <code>true</code>) or the remote has not been fetched (i.e. this method returns + * <code>false</code>). + * @param resource the local resource + * @return <code>true</code> if the variant associated with the given local + * resource has been cached. + * @throws TeamException */ - public boolean isVariantKnown(IResource resource) throws TeamException { - return remoteCache.isVariantKnown(resource); - } + public abstract boolean isVariantKnown(IResource resource) throws TeamException; /** * This method indicates whether the remote bytes are a later revision or version @@ -115,17 +125,17 @@ public abstract class DescendantResourceVariantTree extends ResourceVariantTree protected abstract boolean isDescendant(IResource resource, byte[] baseBytes, byte[] remoteBytes) throws TeamException; /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#setVariantDoesNotExist(org.eclipse.core.resources.IResource) + * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#setVariantDoesNotExist(org.eclipse.core.resources.IResource) */ - public boolean setVariantDoesNotExist(IResource resource) throws TeamException { - return remoteCache.setVariantDoesNotExist(resource); + public boolean deleteBytes(IResource resource) throws TeamException { + return remoteCache.deleteBytes(resource); } /** * Return the base tree from which the remote is descendant. * @return Returns the base tree. */ - protected ResourceVariantTree getBaseTree() { + protected ResourceVariantByteStore getBaseTree() { return baseCache; } @@ -134,15 +144,29 @@ public abstract class DescendantResourceVariantTree extends ResourceVariantTree * that differ from those in the base tree. * @return Returns the remote tree. */ - protected ResourceVariantTree getRemoteTree() { + protected ResourceVariantByteStore getRemoteTree() { return remoteCache; } /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#members(org.eclipse.core.resources.IResource) + * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#members(org.eclipse.core.resources.IResource) */ public IResource[] members(IResource resource) throws TeamException { - return getRemoteTree().members(resource); + IResource[] remoteMembers = getRemoteTree().members(resource); + IResource[] baseMembers = getBaseTree().members(resource); + Set members = new HashSet(); + for (int i = 0; i < remoteMembers.length; i++) { + members.add(remoteMembers[i]); + } + for (int i = 0; i < baseMembers.length; i++) { + IResource member = baseMembers[i]; + // Add the base only inf the remote does not know about it + // (i.e. hasn't marked it as deleted + if (!isVariantKnown(member)) { + members.add(member); + } + } + return (IResource[]) members.toArray(new IResource[members.size()]); } } 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 new file mode 100644 index 000000000..5bbfbd1b0 --- /dev/null +++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/IResourceVariantTree.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * 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 org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.core.synchronize.IResourceVariant; + +/** + * A handle that provides access to locally cached resource variants that + * represent a resource line-up such as a project version or branch. + */ +public interface IResourceVariantTree { + + public abstract IResource[] getRoots(); + + /** + * Returns the members of the local resource that have resource variants in this tree. + * The members may or may not exist locally. The resource variants corresponding to the + * memebers can be retrieved using <code>getResourceVariant(IResource)</code>. + * @param resource the local resource + * @return the members of the local resource for which this tree contains resource variants + * @throws TeamException + */ + public abstract IResource[] members(IResource resource) throws TeamException; + + public abstract IResourceVariant getResourceVariant(IResource resource) throws TeamException; + + /** + * Refreshes the resource variant tree for the specified resources and possibly + * their descendants, depending on the depth. + * @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 variants have changed + * as a result of the refresh + * @throws TeamException + */ + public abstract IResource[] refresh( + IResource[] resources, + int depth, + IProgressMonitor monitor) throws TeamException; +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/PersistantResourceVariantTree.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/PersistantResourceVariantByteStore.java index d998c9cd7..0ea8d7739 100644 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/PersistantResourceVariantTree.java +++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/PersistantResourceVariantByteStore.java @@ -20,11 +20,11 @@ import org.eclipse.team.core.TeamException; import org.eclipse.team.internal.core.Assert; /** - * A <code>ResourceVariantTree</code> that caches the variant bytes using + * A <code>ResourceVariantByteStore</code> that caches the variant bytes using * the <code>org.eclipse.core.resources.ISynchronizer</code> so that * the tree is cached accross workbench invocations. */ -public class PersistantResourceVariantTree extends ResourceVariantTree { +public class PersistantResourceVariantByteStore extends ResourceVariantByteStore { private static final byte[] NO_REMOTE = new byte[0]; @@ -37,13 +37,13 @@ public class PersistantResourceVariantTree extends ResourceVariantTree { * and a unique id within the plugin as the qualifier name. * @param name the key used in the Core synchronizer */ - public PersistantResourceVariantTree(QualifiedName name) { + public PersistantResourceVariantByteStore(QualifiedName name) { syncName = name; getSynchronizer().add(syncName); } /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#dispose() + * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#dispose() */ public void dispose() { getSynchronizer().remove(getSyncName()); @@ -65,7 +65,7 @@ public class PersistantResourceVariantTree extends ResourceVariantTree { } /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#getBytes(org.eclipse.core.resources.IResource) + * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#getBytes(org.eclipse.core.resources.IResource) */ public byte[] getBytes(IResource resource) throws TeamException { byte[] syncBytes = internalGetSyncBytes(resource); @@ -85,7 +85,7 @@ public class PersistantResourceVariantTree extends ResourceVariantTree { } /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#setBytes(org.eclipse.core.resources.IResource, byte[]) + * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#setBytes(org.eclipse.core.resources.IResource, byte[]) */ public boolean setBytes(IResource resource, byte[] bytes) throws TeamException { Assert.isNotNull(bytes); @@ -100,9 +100,9 @@ public class PersistantResourceVariantTree extends ResourceVariantTree { } /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#removeBytes(org.eclipse.core.resources.IResource, int) + * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#removeBytes(org.eclipse.core.resources.IResource, int) */ - public boolean removeBytes(IResource resource, int depth) throws TeamException { + public boolean flushBytes(IResource resource, int depth) throws TeamException { if (resource.exists() || resource.isPhantom()) { try { if (depth != IResource.DEPTH_ZERO || internalGetSyncBytes(resource) != null) { @@ -117,7 +117,7 @@ public class PersistantResourceVariantTree extends ResourceVariantTree { } /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#isVariantKnown(org.eclipse.core.resources.IResource) + * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#isVariantKnown(org.eclipse.core.resources.IResource) */ public boolean isVariantKnown(IResource resource) throws TeamException { return internalGetSyncBytes(resource) != null; @@ -130,12 +130,12 @@ public class PersistantResourceVariantTree extends ResourceVariantTree { * <code>getSyncBytes(resource)</code> will return <code>null</code>. * @return <code>true</code> if this changes the remote sync bytes */ - public boolean setVariantDoesNotExist(IResource resource) throws TeamException { + public boolean deleteBytes(IResource resource) throws TeamException { return setBytes(resource, NO_REMOTE); } /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#members(org.eclipse.core.resources.IResource) + * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#members(org.eclipse.core.resources.IResource) */ public IResource[] members(IResource resource) throws TeamException { if(resource.getType() == IResource.FILE) { diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/ResourceVariantByteStore.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/ResourceVariantByteStore.java new file mode 100644 index 000000000..bf51f5a6a --- /dev/null +++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/ResourceVariantByteStore.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * 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 org.eclipse.core.resources.IResource; +import org.eclipse.team.core.TeamException; + +/** + * The purpose of a <code>ResourceVariantByteStore</code> is to support the caching of + * the synchronization bytes for the resource variants that represent + * a resource line-up of interest such as a version, baseline or branch. The + * cache stores bytes in order to minimize the memory footprint of the tree. It is the + * reponsibility of the client of this API to cache enough bytes to meaningfully identify + * a resource variant (and possibly create an {@link IResourceVariant} handle from them). + * <p> + * The bytes for + * a resource variant are accessed using the local handle that corresponds to the + * resource variant (using the <code>getSyncInfo</code> method). + * The potential children of a resource variant are also accessed + * by using the local handle that corresponds to the resource variant + * (using the <code>members</code> method). + */ +public abstract class ResourceVariantByteStore { + + /** + * Dispose of any cached sync bytes when this cache is no longer needed. + */ + public abstract void dispose(); + + /** + * Return the bytes for the variant corresponding the given local resource. + * A return value of <code>null</code> means that no bytes have been stored + * for the resource variant. It is up to the client to determine whether + * this means that the resource variant does not exist or that it has not been + * fetched or otherwise determined yet. + * @param resource the local resource + * @return the bytes that represent the resource's variant + * @throws TeamException + */ + public abstract byte[] getBytes(IResource resource) throws TeamException; + + /** + * Set the bytes for the variant corresponding the given local resource. + * The bytes should never be <code>null</code>. If it is known that the remote + * does not exist, <code>deleteBytes(IResource)</code> should be used instead. + * If the sync bytes for the remote are stale and should be removed, + * <code>flushBytes(IResouce, int)</code> should be called. + * @param resource the local resource + * @param bytes the bytes that represent the resource's variant + * @return <code>true</code> if the bytes changed + * @throws TeamException + */ + public abstract boolean setBytes(IResource resource, byte[] bytes) throws TeamException; + + /** + * Remove the bytes from the tree for the resource variants corresponding to the + * given local resource and its descendants to the given depth. + * After the bytes are removed, <code>getBytes(resource)</code> will + * return <code>null</code> for the affected resources. + * @param resource the local resource + * @param depth the depth of the operation (one of <code>IResource.DEPTH_ZERO</code>, + * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>) + * @return <code>true</code> if there were bytes present which were removed + * @throws TeamException + */ + public abstract boolean flushBytes(IResource resource, int depth) throws TeamException; + + /** + * Method called to indicate that it is known that there is no variant associated + * with the local resource. Subclasses may handle this information in different ways. + * The <code>flush(IResource, int)</code> method should be used in the cases + * where a client wishes to remove bytes for other reason. + * @param resource the local resource + * @return <code>true</code> if this changes the bytes for the variant + */ + public abstract boolean deleteBytes(IResource resource) throws TeamException; + + /** + * Return the children of the given resource that have resource variants in this tree. + * @param resource the parent resource + * @return the members who have resource variants in this tree. + */ + public abstract IResource[] members(IResource resource) throws TeamException; + + /** + * Helper method to compare two byte arrays for equality + * @param syncBytes1 the first byte array or <code>null</code> + * @param syncBytes2 the second byte array or <code>null</code> + * @return whetehr the two arrays are equal (i.e. same content) + */ + protected boolean equals(byte[] syncBytes1, byte[] syncBytes2) { + if (syncBytes1 == null) { + return syncBytes2 == null; + } else if (syncBytes2 == null) { + return false; + } + if (syncBytes1.length != syncBytes2.length) return false; + for (int i = 0; i < syncBytes1.length; i++) { + if (syncBytes1[i] != syncBytes2[i]) return false; + } + return true; + } +} 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 36404a5c5..13c6566b5 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,120 +10,333 @@ *******************************************************************************/ package org.eclipse.team.internal.core.subscribers.caches; +import java.util.*; + +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.team.core.TeamException; +import org.eclipse.team.core.synchronize.IResourceVariant; +import org.eclipse.team.internal.core.Assert; +import org.eclipse.team.internal.core.Policy; /** - * The purpose of a <code>ResourceVariantTree</code> is to support the caching of - * the synchronization bytes for the resource variants that represent - * a resource line-up of interest such as a version, baseline or branch. The - * cache stores bytes in order to minimize the memory footprint of the tree. It is the - * reponsibility of the client of this API to cache enough bytes to meaningfully identify - * a resource variant (and possibly create an {@link IResourceVariant} handle from them). - * <p> - * The bytes for - * a resource variant are accessed using the local handle that corresponds to the - * resource variant (using the <code>getSyncInfo</code> method). - * The potential children of a resource variant are also accessed - * by using the local handle that corresponds to the resource variant - * (using the <code>members</code> method). - * TODO: Does the isRemoteKnown/setRemoteDoesNotExist make sense? + * This class provides the logic for refreshing a resource variant tree. + * It provides the logic to traverse the local resource and variant resource trees in + * order to update the bytes stored in + * a <code>ResourceVariantByteStore</code>. It also accumulates and returns all local resources + * for which the corresponding resource variant has changed. */ -public abstract class ResourceVariantTree { - - /** - * Dispose of any cached sync bytes when this cache is no longer needed. +public abstract class ResourceVariantTree implements IResourceVariantTree { + + /* (non-Javadoc) + * @see org.eclipse.team.internal.core.subscribers.caches.IResourceVariantTree#members(org.eclipse.core.resources.IResource) */ - public abstract void dispose(); + public IResource[] members(IResource resource) throws TeamException { + return getByteStore().members(resource); + } /** - * Return the bytes for the variant corresponding the given local resource. - * A return value of <code>null</code> can mean either that the - * variant has never been fetched or that it doesn't exist. The method - * <code>isVariantKnown(IResource)</code> should be used to differentiate - * these two cases. - * @param resource the local resource - * @return the bytes that represent the resource's variant + * 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 abstract byte[] getBytes(IResource resource) 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()]); + } + /** - * Set the bytes for the variant corresponding the given local resource. - * The bytes should never be - * <code>null</code>. If it is known that the remote does not exist, - * <code>setVariantDoesNotExist(IResource)</code> should be used instead. If the sync - * bytes for the remote are stale and should be removed, <code>removeBytes()</code> - * should be called. - * @param resource the local resource - * @param bytes the bytes that represent the resource's variant - * @return <code>true</code> if the bytes changed + * 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 */ - public abstract boolean setBytes(IResource resource, byte[] bytes) 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(); + } /** - * Remove the bytes from the tree for the resource variants corresponding to the - * local resources that are descendants of the giben locla resource to the given depth. - * After the bytes are removed, the operation <code>isVariantKnown(resource)</code> - * will return <code>false</code> - * and <code>getBytes(resource)</code> will return <code>null</code> for the - * affected resources. - * @param resource the local resource - * @parem depth the depth of the operation (one of <code>IResource.DEPTH_ZERO</code>, + * 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>) - * @return <code>true</code> if there were bytes present which were removed + * @param monitor a progress monitor + * @return the resource's whose variants have changed * @throws TeamException */ - public abstract boolean removeBytes(IResource resource, int depth) 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()]); + } /** - * Return <code>true</code> if the variant associated with the given local - * resource has been cached. This method is useful for those cases when - * there are no bytes for a resource variant and the client wants to - * know if this means that the remote does exist (i.e. this method returns - * <code>true</code>) or the remote has not been fetched (i.e. this method returns - * <code>false</code>). - * @param resource the local resource - * @return <code>true</code> if the variant associated with the given local - * resource has been cached. - * @throws TeamException + * 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. */ - public abstract boolean isVariantKnown(IResource resource) throws TeamException; + protected abstract ResourceVariantByteStore getByteStore(); /** - * This method should be invoked by a client to indicate that it is known that - * there is no variant associated with the local resource. After this method - * is invoked, <code>isVariantKnown(resource)</code> will return <code>true</code> and - * <code>getBytes(resource)</code> will return <code>null</code>. - * @param resource the local resource - * @return <code>true</code> if this changes the bytes for the variant + * Get the bytes to be stored in the <code>ResourceVariantByteStore</code> + * from the given resource variant. + * @param local the local resource + * @param remote the corresponding resource variant handle + * @return the bytes for the resource variant. */ - public abstract boolean setVariantDoesNotExist(IResource resource) throws TeamException; + protected abstract byte[] getBytes(IResource local, IResourceVariant remote) throws TeamException; /** - * Return the children of the given resource that have resource variants in this tree. - * @param resource the parent resource - * @return the members who have resource variants in this tree. + * 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. */ - public abstract IResource[] members(IResource resource) throws TeamException; - + protected abstract IResourceVariant[] fetchMembers(IResourceVariant variant, IProgressMonitor progress) throws TeamException; + /** - * Helper method to compare two byte arrays for equality - * @param syncBytes1 the first byte array or <code>null</code> - * @param syncBytes2 the second byte array or <code>null</code> - * @return whetehr the two arrays are equal (i.e. same content) + * 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 { + 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 { + // Look for resources that have sync bytes but are not in the resources we care about + ResourceVariantByteStore cache = getByteStore(); + IResource[] resources = getChildrenWithBytes(local); + for (int i = 0; i < resources.length; i++) { + IResource resource = resources[i]; + if (!children.containsKey(resource)) { + // These sync bytes are stale. Purge them + cache.flushBytes(resource, IResource.DEPTH_INFINITE); + changedResources.add(resource); + } + } + } + + /* + * 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. + * @throws TeamException + */ + private IResource[] getChildrenWithBytes(IResource local) throws TeamException { + try { + if (local.getType() != IResource.FILE && (local.exists() || local.isPhantom())) { + // TODO: Not very generic! + IResource[] allChildren = ((IContainer)local).members(true /* include phantoms */); + List childrenWithSyncBytes = new ArrayList(); + for (int i = 0; i < allChildren.length; i++) { + IResource resource = allChildren[i]; + if (getByteStore().getBytes(resource) != null) { + childrenWithSyncBytes.add(resource); + } + } + return (IResource[]) childrenWithSyncBytes.toArray( + new IResource[childrenWithSyncBytes.size()]); + } + } catch (CoreException e) { + throw TeamException.asTeamException(e); + } + 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; + } + + /* + * 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 */ - protected boolean equals(byte[] syncBytes1, byte[] syncBytes2) { - if (syncBytes1 == null) { - return syncBytes2 == null; - } else if (syncBytes2 == null) { - return false; + private IResource getResourceChild(IResource parent, String childName, boolean isContainer) { + if (parent.getType() == IResource.FILE) { + return null; } - if (syncBytes1.length != syncBytes2.length) return false; - for (int i = 0; i < syncBytes1.length; i++) { - if (syncBytes1[i] != syncBytes2[i]) return false; + if (isContainer) { + return ((IContainer) parent).getFolder(new Path(childName)); + } else { + return ((IContainer) parent).getFile(new Path(childName)); } - return true; } } diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/ResourceVariantTreeRefresh.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/ResourceVariantTreeRefresh.java deleted file mode 100644 index 1c7395c7e..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/ResourceVariantTreeRefresh.java +++ /dev/null @@ -1,339 +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.core.subscribers.caches; - -import java.util.*; - -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.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. - * It provides the logic to traverse the local resource and variant resource trees in - * order to update the bytes stored in - * a <code>ResourceVariantTree</code>. It also accumulates and returns all local resources - * for which the corresponding resource variant has changed. - */ -public abstract class ResourceVariantTreeRefresh { - - /** - * 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; - } - - /** - * 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()]); - } - - /** - * Returns the resource variant tree that is being refreshed. - * @return the resource variant tree that is being refreshed. - */ - protected abstract ResourceVariantTree getResourceVariantTree(); - - /** - * Get the bytes to be stored in the <code>ResourceVariantTree</code> - * from the given resource variant. - * @param local the local resource - * @param remote the corresponding resource variant handle - * @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; - - /** - * Returns the members of the local resource. This may include all the members of - * the local resource or a subset that is of ineterest to the implementor. - * @param parent the local resource - * @return the members of the local resource - */ - protected abstract IResource[] members(IResource parent) 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; - - /** - * 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(); - } - - private void collectChanges(IResource local, IResourceVariant remote, Collection changedResources, int depth, IProgressMonitor monitor) throws TeamException { - ResourceVariantTree cache = getResourceVariantTree(); - byte[] newRemoteBytes = getBytes(local, remote); - boolean changed; - if (newRemoteBytes == null) { - changed = cache.setVariantDoesNotExist(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 { - // Look for resources that have sync bytes but are not in the resources we care about - ResourceVariantTree cache = getResourceVariantTree(); - IResource[] resources = getChildrenWithBytes(local); - for (int i = 0; i < resources.length; i++) { - IResource resource = resources[i]; - if (!children.containsKey(resource)) { - // These sync bytes are stale. Purge them - cache.removeBytes(resource, IResource.DEPTH_INFINITE); - changedResources.add(resource); - } - } - } - - /* - * 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. - * @throws TeamException - */ - private IResource[] getChildrenWithBytes(IResource local) throws TeamException { - try { - if (local.getType() != IResource.FILE && (local.exists() || local.isPhantom())) { - IResource[] allChildren = ((IContainer)local).members(true /* include phantoms */); - List childrenWithSyncBytes = new ArrayList(); - for (int i = 0; i < allChildren.length; i++) { - IResource resource = allChildren[i]; - if (getResourceVariantTree().getBytes(resource) != null) { - childrenWithSyncBytes.add(resource); - } - } - return (IResource[]) childrenWithSyncBytes.toArray( - new IResource[childrenWithSyncBytes.size()]); - } - } catch (CoreException e) { - throw TeamException.asTeamException(e); - } - return new IResource[0]; - } - - private Map mergedMembers(IResource local, IResourceVariant remote, IProgressMonitor progress) throws TeamException { - - // {IResource -> IRemoteResource} - 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; - } - - /* - * Create a local resource handle for a resource variant whose - * corresponding local resource does not exist. - * @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 - */ - 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/SessionResourceVariantTree.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/SessionResourceVariantByteStore.java index 59dacc2b8..cc32236cc 100644 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/SessionResourceVariantTree.java +++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/caches/SessionResourceVariantByteStore.java @@ -18,10 +18,10 @@ import org.eclipse.team.core.TeamException; import org.eclipse.team.internal.core.Assert; /** - * A <code>ResourceVariantTree</code> that caches the variant bytes in memory + * A <code>ResourceVariantByteStore</code> that caches the variant bytes in memory * and does not persist them over workbench invocations. */ -public class SessionResourceVariantTree extends ResourceVariantTree { +public class SessionResourceVariantByteStore extends ResourceVariantByteStore { private static final byte[] NO_REMOTE = new byte[0]; @@ -64,7 +64,7 @@ public class SessionResourceVariantTree extends ResourceVariantTree { } /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#dispose() + * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#dispose() */ public void dispose() { syncBytesCache.clear(); @@ -72,7 +72,7 @@ public class SessionResourceVariantTree extends ResourceVariantTree { } /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#getBytes(org.eclipse.core.resources.IResource) + * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#getBytes(org.eclipse.core.resources.IResource) */ public byte[] getBytes(IResource resource) throws TeamException { byte[] syncBytes = internalGetSyncBytes(resource); @@ -85,7 +85,7 @@ public class SessionResourceVariantTree extends ResourceVariantTree { /* * (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#setBytes(org.eclipse.core.resources.IResource, byte[]) + * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#setBytes(org.eclipse.core.resources.IResource, byte[]) */ public boolean setBytes(IResource resource, byte[] bytes) throws TeamException { Assert.isNotNull(bytes); @@ -96,15 +96,15 @@ public class SessionResourceVariantTree extends ResourceVariantTree { } /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#removeBytes(org.eclipse.core.resources.IResource, int) + * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#removeBytes(org.eclipse.core.resources.IResource, int) */ - public boolean removeBytes(IResource resource, int depth) throws TeamException { + public boolean flushBytes(IResource resource, int depth) throws TeamException { if (getSyncBytesCache().containsKey(resource)) { if (depth != IResource.DEPTH_ZERO) { IResource[] members = members(resource); for (int i = 0; i < members.length; i++) { IResource child = members[i]; - removeBytes(child, (depth == IResource.DEPTH_INFINITE) ? IResource.DEPTH_INFINITE: IResource.DEPTH_ZERO); + flushBytes(child, (depth == IResource.DEPTH_INFINITE) ? IResource.DEPTH_INFINITE: IResource.DEPTH_ZERO); } } getSyncBytesCache().remove(resource); @@ -115,7 +115,7 @@ public class SessionResourceVariantTree extends ResourceVariantTree { } /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#members(org.eclipse.core.resources.IResource) + * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#members(org.eclipse.core.resources.IResource) */ public IResource[] members(IResource resource) { List members = (List)membersCache.get(resource); @@ -126,17 +126,10 @@ public class SessionResourceVariantTree extends ResourceVariantTree { } /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#isVariantKnown(org.eclipse.core.resources.IResource) + * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#setVariantDoesNotExist(org.eclipse.core.resources.IResource) */ - public boolean isVariantKnown(IResource resource) throws TeamException { - return internalGetSyncBytes(resource) != null; - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree#setVariantDoesNotExist(org.eclipse.core.resources.IResource) - */ - public boolean setVariantDoesNotExist(IResource resource) throws TeamException { - return setBytes(resource, NO_REMOTE); + public boolean deleteBytes(IResource resource) throws TeamException { + return flushBytes(resource, IResource.DEPTH_ZERO); } /** 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 6f496f55d..80ee96bbf 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 @@ -16,9 +16,11 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.team.core.TeamException; import org.eclipse.team.core.subscribers.*; +import org.eclipse.team.core.synchronize.IResourceVariant; import org.eclipse.team.core.synchronize.SyncInfo; -import org.eclipse.team.internal.core.subscribers.caches.SessionResourceVariantTree; -import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree; +import org.eclipse.team.internal.ccvs.core.syncinfo.CVSBaseSynchronizationCache; +import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore; +import org.eclipse.team.internal.core.subscribers.caches.SessionResourceVariantByteStore; /** * This subscriber is used when comparing the local workspace with its @@ -30,7 +32,7 @@ public class CVSCompareSubscriber extends CVSSyncTreeSubscriber implements ISubs private static final String UNIQUE_ID_PREFIX = "compare-"; //$NON-NLS-1$ private CVSTag tag; - private SessionResourceVariantTree remoteSynchronizer; + private SessionResourceVariantByteStore remoteSynchronizer; private IResource[] resources; public CVSCompareSubscriber(IResource[] resources, CVSTag tag) { @@ -41,7 +43,7 @@ public class CVSCompareSubscriber extends CVSSyncTreeSubscriber implements ISubs } private void initialize() { - remoteSynchronizer = new SessionResourceVariantTree(); + remoteSynchronizer = new SessionResourceVariantByteStore(); CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().addListener(this); } @@ -73,7 +75,7 @@ public class CVSCompareSubscriber extends CVSSyncTreeSubscriber implements ISubs /* (non-Javadoc) * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getBaseSynchronizationCache() */ - protected ResourceVariantTree getBaseSynchronizationCache() { + protected ResourceVariantByteStore getBaseSynchronizationCache() { // No base cache needed since it's a two way compare return null; } @@ -81,7 +83,7 @@ public class CVSCompareSubscriber extends CVSSyncTreeSubscriber implements ISubs /* (non-Javadoc) * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getRemoteSynchronizationCache() */ - protected ResourceVariantTree getRemoteSynchronizationCache() { + protected ResourceVariantByteStore getRemoteSynchronizationCache() { return remoteSynchronizer; } @@ -182,9 +184,16 @@ public class CVSCompareSubscriber extends CVSSyncTreeSubscriber implements ISubs * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getSyncInfo(org.eclipse.core.resources.IResource) */ public SyncInfo getSyncInfo(IResource resource) throws TeamException { + // TODO: Temporary measure to avoid showing all local as additions before the refresh completes if (remoteSynchronizer.isEmpty()) { - return null; + // Use the base as the remote so that outgoing changes are included + return new CVSSyncInfo(resource, null, getBase(resource), this); } return super.getSyncInfo(resource); } + + private CVSBaseSynchronizationCache baseCache = new CVSBaseSynchronizationCache(); + private IResourceVariant getBase(IResource resource) throws TeamException { + return getRemoteResource(resource, baseCache); + } } 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 26851a8bb..500ce8d47 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 @@ -23,8 +23,8 @@ 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.ResourceSyncInfo; import org.eclipse.team.internal.ccvs.core.util.Util; -import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree; -import org.eclipse.team.internal.core.subscribers.caches.PersistantResourceVariantTree; +import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore; +import org.eclipse.team.internal.core.subscribers.caches.PersistantResourceVariantByteStore; /** * A CVSMergeSubscriber is responsible for maintaining the remote trees for a merge into @@ -48,9 +48,9 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour private CVSTag start, end; private List roots; - private ResourceVariantTree remoteSynchronizer; - private PersistantResourceVariantTree mergedSynchronizer; - private ResourceVariantTree baseSynchronizer; + private CVSSynchronizationCache remoteSynchronizer; + private PersistantResourceVariantByteStore mergedSynchronizer; + private CVSSynchronizationCache baseSynchronizer; public CVSMergeSubscriber(IResource[] roots, CVSTag start, CVSTag end) { this(getUniqueId(), roots, start, end); @@ -77,7 +77,7 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour 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())); - mergedSynchronizer = new PersistantResourceVariantTree(new QualifiedName(SYNC_KEY_QUALIFIER, syncKeyPrefix + "0merged")); //$NON-NLS-1$ + mergedSynchronizer = new PersistantResourceVariantByteStore(new QualifiedName(SYNC_KEY_QUALIFIER, syncKeyPrefix + "0merged")); //$NON-NLS-1$ ResourcesPlugin.getWorkspace().addResourceChangeListener(this); CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().addListener(this); @@ -100,7 +100,7 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour private void internalMerged(IResource resource) throws TeamException { byte[] remoteBytes = remoteSynchronizer.getBytes(resource); if (remoteBytes == null) { - mergedSynchronizer.setVariantDoesNotExist(resource); + mergedSynchronizer.deleteBytes(resource); } else { mergedSynchronizer.setBytes(resource, remoteBytes); } @@ -238,14 +238,14 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour /* (non-Javadoc) * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getBaseSynchronizationCache() */ - protected ResourceVariantTree getBaseSynchronizationCache() { + protected ResourceVariantByteStore getBaseSynchronizationCache() { return baseSynchronizer; } /* (non-Javadoc) * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getRemoteSynchronizationCache() */ - protected ResourceVariantTree getRemoteSynchronizationCache() { + protected ResourceVariantByteStore getRemoteSynchronizationCache() { return remoteSynchronizer; } @@ -326,6 +326,11 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour if (parentBytes != null) { return RemoteFile.fromBytes(resource, mergedBytes, parentBytes); } + } else { + // A deletion was merged so return null for the base + if (mergedSynchronizer.isVariantKnown(resource)) { + return null; + } } return super.getBaseResource(resource); } 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 2cb785bd7..4bc1dca7b 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 @@ -213,14 +213,14 @@ public abstract class CVSSyncTreeSubscriber extends SyncTreeSubscriber { /** * Return the synchronization cache that provides access to the base sychronization bytes. */ - protected abstract ResourceVariantTree getBaseSynchronizationCache(); + protected abstract ResourceVariantByteStore getBaseSynchronizationCache(); /** * Return the synchronization cache that provides access to the base sychronization bytes. */ - protected abstract ResourceVariantTree getRemoteSynchronizationCache(); + protected abstract ResourceVariantByteStore getRemoteSynchronizationCache(); - protected IResourceVariant getRemoteResource(IResource resource, ResourceVariantTree cache) throws TeamException { + 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 @@ -260,9 +260,9 @@ public abstract class CVSSyncTreeSubscriber extends SyncTreeSubscriber { } } - private String getSyncName(ResourceVariantTree cache) { - if (cache instanceof PersistantResourceVariantTree) { - return ((PersistantResourceVariantTree)cache).getSyncName().toString(); + private String getSyncName(ResourceVariantByteStore cache) { + if (cache instanceof PersistantResourceVariantByteStore) { + return ((PersistantResourceVariantByteStore)cache).getSyncName().toString(); } return cache.getClass().getName(); } @@ -316,7 +316,7 @@ public abstract class CVSSyncTreeSubscriber extends SyncTreeSubscriber { } } - private IResource[] getMembers(ResourceVariantTree cache, IResource resource) throws TeamException, CoreException { + private IResource[] getMembers(ResourceVariantByteStore cache, IResource resource) throws TeamException, CoreException { // Filter and return only phantoms associated with the remote synchronizer. IResource[] members; try { 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 4be128a42..3fb66fe63 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 @@ -25,8 +25,8 @@ 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.util.ResourceStateChangeListeners; -import org.eclipse.team.internal.core.subscribers.caches.PersistantResourceVariantTree; -import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree; +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; /** @@ -34,8 +34,8 @@ import org.eclipse.team.internal.ccvs.core.Policy; */ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IResourceStateChangeListener { - private ResourceVariantTree remoteSynchronizer; - private ResourceVariantTree baseSynchronizer; + private CVSDescendantSynchronizationCache remoteSynchronizer; + private ResourceVariantByteStore baseSynchronizer; // qualified name for remote sync info private static final String REMOTE_RESOURCE_KEY = "remote-resource-key"; //$NON-NLS-1$ @@ -47,7 +47,7 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe baseSynchronizer = new CVSBaseSynchronizationCache(); remoteSynchronizer = new CVSDescendantSynchronizationCache( baseSynchronizer, - new PersistantResourceVariantTree(new QualifiedName(SYNC_KEY_QUALIFIER, REMOTE_RESOURCE_KEY))); + new PersistantResourceVariantByteStore(new QualifiedName(SYNC_KEY_QUALIFIER, REMOTE_RESOURCE_KEY))); ResourceStateChangeListeners.getListener().addResourceStateChangeListener(this); } @@ -96,7 +96,7 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe // managed then this information is stale if (getBaseSynchronizationCache().getBytes(resource) != null) { if (canModifyWorkspace) { - remoteSynchronizer.removeBytes(resource, IResource.DEPTH_ZERO); + remoteSynchronizer.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) @@ -107,7 +107,7 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe byte[] localBytes = baseSynchronizer.getBytes(resource); if (localBytes == null || !isLaterRevision(remoteBytes, localBytes)) { if (canModifyWorkspace) { - remoteSynchronizer.removeBytes(resource, IResource.DEPTH_ZERO); + remoteSynchronizer.flushBytes(resource, IResource.DEPTH_ZERO); } else { // The getRemoteResource method handles the stale sync bytes } @@ -116,7 +116,7 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe } 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.removeBytes(resource, IResource.DEPTH_ZERO); + remoteSynchronizer.flushBytes(resource, IResource.DEPTH_ZERO); } } } catch (TeamException e) { @@ -168,7 +168,7 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe */ public void projectDeconfigured(IProject project) { try { - remoteSynchronizer.removeBytes(project, IResource.DEPTH_INFINITE); + remoteSynchronizer.flushBytes(project, IResource.DEPTH_INFINITE); } catch (TeamException e) { CVSProviderPlugin.log(e); } @@ -212,14 +212,14 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe /* (non-Javadoc) * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getBaseSynchronizationCache() */ - protected ResourceVariantTree getBaseSynchronizationCache() { + protected ResourceVariantByteStore getBaseSynchronizationCache() { return baseSynchronizer; } /* (non-Javadoc) * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getRemoteSynchronizationCache() */ - protected ResourceVariantTree getRemoteSynchronizationCache() { + protected ResourceVariantByteStore getRemoteSynchronizationCache() { return remoteSynchronizer; } 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/CVSBaseSynchronizationCache.java index e3059df18..b1c615668 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/CVSBaseSynchronizationCache.java @@ -13,11 +13,11 @@ package org.eclipse.team.internal.ccvs.core.syncinfo; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IResource; import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree; +import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore; import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer; -public class CVSBaseSynchronizationCache extends ResourceVariantTree { +public class CVSBaseSynchronizationCache extends ResourceVariantByteStore { public void dispose() { // Do nothing } @@ -44,13 +44,13 @@ public class CVSBaseSynchronizationCache extends ResourceVariantTree { public boolean isVariantKnown(IResource resource) throws TeamException { return getBytes(resource) != null; } - public boolean removeBytes(IResource resource, int depth) throws TeamException { + public boolean flushBytes(IResource resource, int depth) throws TeamException { throw new UnsupportedOperationException(); } public boolean setBytes(IResource resource, byte[] bytes) throws TeamException { throw new UnsupportedOperationException(); } - public boolean setVariantDoesNotExist(IResource resource) throws TeamException { + public boolean deleteBytes(IResource resource) throws TeamException { throw new UnsupportedOperationException(); } 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/CVSDescendantSynchronizationCache.java index a3c413710..7baefb8cc 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/CVSDescendantSynchronizationCache.java @@ -18,9 +18,9 @@ import org.eclipse.team.internal.ccvs.core.*; /** * CVS sycnrhonization cache that ignores stale remote bytes */ -public class CVSDescendantSynchronizationCache extends DescendantResourceVariantTree { +public class CVSDescendantSynchronizationCache extends DescendantResourceVariantByteStore { - public CVSDescendantSynchronizationCache(ResourceVariantTree baseCache, PersistantResourceVariantTree remoteCache) { + public CVSDescendantSynchronizationCache(ResourceVariantByteStore baseCache, PersistantResourceVariantByteStore remoteCache) { super(baseCache, remoteCache); } @@ -44,7 +44,7 @@ public class CVSDescendantSynchronizationCache extends DescendantResourceVariant 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", ((PersistantResourceVariantTree)getRemoteTree()).getSyncName().toString(), resource.getFullPath().toString()))); //$NON-NLS-1$ + CVSProviderPlugin.log(new TeamException(Policy.bind("ResourceSynchronizer.missingParentBytesOnSet", ((PersistantResourceVariantByteStore)getRemoteTree()).getSyncName().toString(), resource.getFullPath().toString()))); //$NON-NLS-1$ } return changed; } @@ -59,4 +59,10 @@ public class CVSDescendantSynchronizationCache extends DescendantResourceVariant return (getBytes(resource.getParent()) != null); } + /* (non-Javadoc) + * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#isVariantKnown(org.eclipse.core.resources.IResource) + */ + public boolean isVariantKnown(IResource resource) throws TeamException { + return ((PersistantResourceVariantByteStore)getRemoteTree()).isVariantKnown(resource); + } } 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 index 395166a28..829a34dd6 100644 --- 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 @@ -10,10 +10,6 @@ *******************************************************************************/ package org.eclipse.team.internal.ccvs.core.syncinfo; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.team.core.TeamException; @@ -21,19 +17,20 @@ 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; -import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTreeRefresh; /** * CVS Specific refresh operation */ -public class CVSRefreshOperation extends ResourceVariantTreeRefresh { +public class CVSRefreshOperation extends ResourceVariantTree { - private ResourceVariantTree cache, baseCache; + private ResourceVariantByteStore cache, baseCache; private CVSTag tag; private boolean cacheFileContentsHint; + private CVSSyncTreeSubscriber subscriber; - public CVSRefreshOperation(ResourceVariantTree cache, ResourceVariantTree baseCache, CVSTag tag, boolean cacheFileContentsHint) { + public CVSRefreshOperation(ResourceVariantByteStore cache, ResourceVariantByteStore baseCache, CVSTag tag, boolean cacheFileContentsHint) { this.tag = tag; this.cache = cache; this.baseCache = cache; @@ -43,7 +40,7 @@ public class CVSRefreshOperation extends ResourceVariantTreeRefresh { /* (non-Javadoc) * @see org.eclipse.team.core.subscribers.RefreshOperation#getSynchronizationCache() */ - protected ResourceVariantTree getResourceVariantTree() { + protected ResourceVariantByteStore getByteStore() { return cache; } @@ -75,31 +72,6 @@ public class CVSRefreshOperation extends ResourceVariantTreeRefresh { } /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.RefreshOperation#getLocalChildren(org.eclipse.core.resources.IResource) - */ - protected IResource[] members(IResource local) throws TeamException { - IResource[] localChildren = null; - if( local.getType() != IResource.FILE && (local.exists() || local.isPhantom())) { - // Include all non-ignored resources including outgoing deletions - ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor((IContainer)local); - // Look inside existing folders and phantoms that are CVS folders - if (local.exists() || cvsFolder.isCVSFolder()) { - ICVSResource[] cvsChildren = cvsFolder.members(ICVSFolder.MANAGED_MEMBERS | ICVSFolder.UNMANAGED_MEMBERS); - List resourceChildren = new ArrayList(); - for (int i = 0; i < cvsChildren.length; i++) { - ICVSResource cvsResource = cvsChildren[i]; - resourceChildren.add(cvsResource.getIResource()); - } - localChildren = (IResource[]) resourceChildren.toArray(new IResource[resourceChildren.size()]); - } - } - if (localChildren == null) { - localChildren = new IResource[0]; - } - return localChildren; - } - - /* (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 { @@ -117,4 +89,18 @@ public class CVSRefreshOperation extends ResourceVariantTreeRefresh { 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/CVSSynchronizationCache.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSSynchronizationCache.java index e910a03f4..32579df08 100644 --- 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 @@ -13,15 +13,15 @@ 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.PersistantResourceVariantTree; +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>PersistantResourceVariantTree</code> to log an error + * Override <code>PersistantResourceVariantByteStore</code> to log an error * if there are no parent bytes for a file. */ -public class CVSSynchronizationCache extends PersistantResourceVariantTree { +public class CVSSynchronizationCache extends PersistantResourceVariantByteStore { public CVSSynchronizationCache(QualifiedName name) { super(name); diff --git a/bundles/org.eclipse.team.ui/.project b/bundles/org.eclipse.team.ui/.project index 7093fb2b5..340fab81e 100644 --- a/bundles/org.eclipse.team.ui/.project +++ b/bundles/org.eclipse.team.ui/.project @@ -12,6 +12,7 @@ <project>org.eclipse.team.core</project> <project>org.eclipse.ui</project> <project>org.eclipse.ui.editors</project> + <project>org.eclipse.ui.forms</project> <project>org.eclipse.ui.ide</project> <project>org.eclipse.ui.views</project> <project>org.eclipse.ui.workbench.texteditor</project> diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/AllTestsTeamSubscriber.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/AllTestsTeamSubscriber.java index a5905ed4c..4368eb558 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/AllTestsTeamSubscriber.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/AllTestsTeamSubscriber.java @@ -28,10 +28,10 @@ public class AllTestsTeamSubscriber extends EclipseTest { public static Test suite() { TestSuite suite = new TestSuite(); - // suite.addTest(CVSMergeSubscriberTest.suite()); - // suite.addTest(CVSWorkspaceSubscriberTest.suite()); + suite.addTest(CVSMergeSubscriberTest.suite()); + suite.addTest(CVSWorkspaceSubscriberTest.suite()); suite.addTest(CVSCompareSubscriberTest.suite()); - // suite.addTest(SyncSetTests.suite()); + suite.addTest(SyncSetTests.suite()); CVSSyncSubscriberTest.setSyncSource(new SynchronizeViewTestAdapter()); return new CVSTestSetup(suite); } diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/SynchronizeViewTestAdapter.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/SynchronizeViewTestAdapter.java index cb59c581f..bcdb06441 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/SynchronizeViewTestAdapter.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/SynchronizeViewTestAdapter.java @@ -43,7 +43,12 @@ public class SynchronizeViewTestAdapter extends SyncInfoSource { if (info == null) { info = subscriber.getSyncInfo(resource); if ((info != null && info.getKind() != SyncInfo.IN_SYNC)) { - throw new AssertionFailedError(); + throw new AssertionFailedError( + "Sync info for " + + resource.getFullPath() + + " was " + + SyncInfo.kindToString(info.getKind()) + + " but resource was not collected"); } } return info; |