From 4a1ca77df6f4238416a8715a8c35819611d5992a Mon Sep 17 00:00:00 2001 From: Jean Michel-Lemieux Date: Wed, 25 Feb 2004 20:34:58 +0000 Subject: SyncView API released to HEAD. --- .../internal/ccvs/core/CVSCompareSubscriber.java | 190 +++++++++ .../internal/ccvs/core/CVSMergeSubscriber.java | 262 +++++++----- .../team/internal/ccvs/core/CVSMergeSyncInfo.java | 17 +- .../team/internal/ccvs/core/CVSProviderPlugin.java | 49 +-- .../core/CVSRevisionNumberCompareCriteria.java | 62 +-- .../team/internal/ccvs/core/CVSSyncInfo.java | 42 +- .../internal/ccvs/core/CVSSyncTreeSubscriber.java | 364 ++++++++--------- .../team/internal/ccvs/core/CVSTeamProvider.java | 17 +- .../internal/ccvs/core/CVSWorkspaceSubscriber.java | 195 ++++----- .../team/internal/ccvs/core/ICVSRemoteFile.java | 10 + .../internal/ccvs/core/ICVSRemoteResource.java | 21 +- .../core/client/listeners/AnnotateListener.java | 5 +- .../core/client/listeners/CompareDiffListener.java | 19 +- .../ccvs/core/client/listeners/DiffListener.java | 14 +- .../core/connection/CVSRepositoryLocation.java | 8 +- .../team/internal/ccvs/core/messages.properties | 8 +- .../ccvs/core/resources/CVSLocalSyncElement.java | 107 ----- .../ccvs/core/resources/CVSRemoteSyncElement.java | 444 --------------------- .../ccvs/core/resources/CVSWorkspaceRoot.java | 115 +----- .../ccvs/core/resources/EclipseSynchronizer.java | 29 +- .../core/resources/FileContentCachingService.java | 8 +- .../core/resources/FileModificationManager.java | 11 +- .../internal/ccvs/core/resources/RemoteFile.java | 204 +++------- .../internal/ccvs/core/resources/RemoteFolder.java | 45 +-- .../ccvs/core/resources/RemoteResource.java | 32 +- .../resources/SessionPropertySyncInfoCache.java | 69 +--- .../ccvs/core/syncinfo/BaseSynchronizer.java | 94 ----- .../core/syncinfo/CVSBaseSynchronizationCache.java | 66 +++ .../CVSDescendantSynchronizationCache.java | 62 +++ .../ccvs/core/syncinfo/CVSRefreshOperation.java | 120 ++++++ .../ccvs/core/syncinfo/CVSRemoteSynchronizer.java | 93 ----- .../core/syncinfo/CVSSynchronizationCache.java | 52 +++ .../syncinfo/DeferredResourceChangeHandler.java | 24 +- .../ccvs/core/syncinfo/MergedSynchronizer.java | 49 --- .../core/syncinfo/OptimizedRemoteSynchronizer.java | 84 ---- .../internal/ccvs/core/syncinfo/ReentrantLock.java | 4 +- .../ccvs/core/syncinfo/RemoteResourceFactory.java | 21 - .../ccvs/core/syncinfo/RemoteTagSynchronizer.java | 257 ------------ .../ccvs/core/syncinfo/ResourceSyncInfo.java | 2 +- .../internal/ccvs/core/util/SyncFileWriter.java | 35 ++ .../eclipse/team/internal/ccvs/core/util/Util.java | 1 + 41 files changed, 1249 insertions(+), 2062 deletions(-) create mode 100644 bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSCompareSubscriber.java delete mode 100644 bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSLocalSyncElement.java delete mode 100644 bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSRemoteSyncElement.java delete mode 100644 bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/BaseSynchronizer.java create mode 100644 bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSBaseSynchronizationCache.java create mode 100644 bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSDescendantSynchronizationCache.java create mode 100644 bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSRefreshOperation.java delete mode 100644 bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSRemoteSynchronizer.java create mode 100644 bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSSynchronizationCache.java delete mode 100644 bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/MergedSynchronizer.java delete mode 100644 bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/OptimizedRemoteSynchronizer.java delete mode 100644 bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/RemoteResourceFactory.java delete mode 100644 bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/RemoteTagSynchronizer.java (limited to 'bundles/org.eclipse.team.cvs.core') 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 new file mode 100644 index 000000000..6f496f55d --- /dev/null +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSCompareSubscriber.java @@ -0,0 +1,190 @@ +/******************************************************************************* + * 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; + +import java.util.*; + +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.SyncInfo; +import org.eclipse.team.internal.core.subscribers.caches.SessionResourceVariantTree; +import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree; + +/** + * This subscriber is used when comparing the local workspace with its + * corresponding remote. + */ +public class CVSCompareSubscriber extends CVSSyncTreeSubscriber implements ISubscriberChangeListener { + + 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 SessionResourceVariantTree remoteSynchronizer; + private IResource[] resources; + + 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; + initialize(); + } + + private void initialize() { + remoteSynchronizer = new SessionResourceVariantTree(); + CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().addListener(this); + } + + public void dispose() { + CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().removeListener(this); + remoteSynchronizer.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 ResourceVariantTree getBaseSynchronizationCache() { + // No base cache needed since it's a two way compare + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getRemoteSynchronizationCache() + */ + protected ResourceVariantTree getRemoteSynchronizationCache() { + return remoteSynchronizer; + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.TeamSubscriber#isThreeWay() + */ + public boolean isThreeWay() { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.TeamSubscriber#roots() + */ + public IResource[] roots() { + return resources; + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.ITeamResourceChangeListener#teamResourceChanged(org.eclipse.team.core.subscribers.TeamDelta[]) + */ + public void subscriberResourceChanged(ISubscriberChangeEvent[] deltas) { + List outgoingDeltas = new ArrayList(deltas.length); + for (int i = 0; i < deltas.length; i++) { + ISubscriberChangeEvent delta = deltas[i]; + if ((delta.getFlags() & ISubscriberChangeEvent.ROOT_REMOVED) != 0) { + IResource resource = delta.getResource(); + outgoingDeltas.addAll(Arrays.asList(handleRemovedRoot(resource))); + } else if ((delta.getFlags() & ISubscriberChangeEvent.SYNC_CHANGED) != 0) { + IResource resource = delta.getResource(); + try { + if (isSupervised(resource)) { + outgoingDeltas.add(new SubscriberChangeEvent(this, delta.getFlags(), resource)); + } + } catch (TeamException e) { + // Log and ignore + CVSProviderPlugin.log(e); + } + } + } + + fireTeamResourceChange((SubscriberChangeEvent[]) outgoingDeltas.toArray(new SubscriberChangeEvent[outgoingDeltas.size()])); + } + + private SubscriberChangeEvent[] handleRemovedRoot(IResource removedRoot) { + // Determine if any of the roots of the compare are affected + List removals = new ArrayList(resources.length); + for (int j = 0; j < resources.length; j++) { + IResource root = resources[j]; + if (removedRoot.getFullPath().isPrefixOf(root.getFullPath())) { + // The root is no longer managed by CVS + removals.add(root); + } + } + if (removals.isEmpty()) { + return new SubscriberChangeEvent[0]; + } + + // Adjust the roots of the subscriber + List newRoots = new ArrayList(resources.length); + newRoots.addAll(Arrays.asList(resources)); + newRoots.removeAll(removals); + resources = (IResource[]) newRoots.toArray(new IResource[newRoots.size()]); + + // Create the deltas for the removals + SubscriberChangeEvent[] deltas = new SubscriberChangeEvent[removals.size()]; + for (int i = 0; i < deltas.length; i++) { + deltas[i] = new SubscriberChangeEvent(this, ISubscriberChangeEvent.ROOT_REMOVED, (IResource)removals.get(i)); + } + return deltas; + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.TeamSubscriber#isSupervised(org.eclipse.core.resources.IResource) + */ + public boolean isSupervised(IResource resource) throws TeamException { + if (super.isSupervised(resource)) { + if (!resource.exists() && getRemoteSynchronizationCache().getBytes(resource) == null) { + // Exclude conflicting deletions + return false; + } + for (int i = 0; i < resources.length; i++) { + IResource root = resources[i]; + if (root.getFullPath().isPrefixOf(resource.getFullPath())) { + return true; + } + } + } + return false; + } + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getCacheFileContentsHint() + */ + protected boolean getCacheFileContentsHint() { + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getSyncInfo(org.eclipse.core.resources.IResource) + */ + public SyncInfo getSyncInfo(IResource resource) throws TeamException { + if (remoteSynchronizer.isEmpty()) { + return null; + } + return super.getSyncInfo(resource); + } +} 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 acfe2467d..26851a8bb 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,31 +10,21 @@ *******************************************************************************/ package org.eclipse.team.internal.ccvs.core; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; -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.core.resources.*; +import org.eclipse.core.runtime.*; import org.eclipse.team.core.RepositoryProvider; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.ContentComparisonCriteria; -import org.eclipse.team.core.subscribers.ITeamResourceChangeListener; -import org.eclipse.team.core.subscribers.RemoteBytesSynchronizer; -import org.eclipse.team.core.subscribers.RemoteSynchronizer; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.core.subscribers.TeamDelta; -import org.eclipse.team.core.sync.IRemoteResource; -import org.eclipse.team.internal.ccvs.core.syncinfo.MergedSynchronizer; -import org.eclipse.team.internal.ccvs.core.syncinfo.RemoteTagSynchronizer; +import org.eclipse.team.core.subscribers.*; +import org.eclipse.team.core.synchronize.*; +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.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; /** * A CVSMergeSubscriber is responsible for maintaining the remote trees for a merge into @@ -51,31 +41,19 @@ import org.eclipse.team.internal.ccvs.core.syncinfo.RemoteTagSynchronizer; * TODO: Do certain operations (e.g. replace with) invalidate a merge subscriber? * TODO: How to ensure that sync info is flushed when merge roots are deleted? */ -public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResourceChangeListener, ITeamResourceChangeListener { +public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResourceChangeListener, ISubscriberChangeListener { public static final String QUALIFIED_NAME = "org.eclipse.team.cvs.ui.cvsmerge-participant"; //$NON-NLS-1$ private static final String UNIQUE_ID_PREFIX = "merge-"; //$NON-NLS-1$ private CVSTag start, end; private List roots; - private RemoteTagSynchronizer remoteSynchronizer; - private RemoteBytesSynchronizer mergedSynchronizer; - private RemoteTagSynchronizer baseSynchronizer; - - private static final byte[] NO_REMOTE = new byte[0]; + private ResourceVariantTree remoteSynchronizer; + private PersistantResourceVariantTree mergedSynchronizer; + private ResourceVariantTree baseSynchronizer; - - protected IResource[] refreshRemote(IResource resource, int depth, IProgressMonitor monitor) throws TeamException { - IResource[] remoteChanges = super.refreshRemote(resource, depth, monitor); - adjustMergedResources(remoteChanges); - return remoteChanges; - } - - private void adjustMergedResources(IResource[] remoteChanges) throws TeamException { - for (int i = 0; i < remoteChanges.length; i++) { - IResource resource = remoteChanges[i]; - mergedSynchronizer.removeSyncBytes(resource, IResource.DEPTH_ZERO); - } + public CVSMergeSubscriber(IResource[] roots, CVSTag start, CVSTag end) { + this(getUniqueId(), roots, start, end); } private static QualifiedName getUniqueId() { @@ -83,10 +61,6 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour return new QualifiedName(QUALIFIED_NAME, "CVS" + UNIQUE_ID_PREFIX + uniqueId); //$NON-NLS-1$ } - public CVSMergeSubscriber(IResource[] roots, CVSTag start, CVSTag end) { - this(getUniqueId(), roots, start, end); - } - public CVSMergeSubscriber(QualifiedName id, IResource[] roots, CVSTag start, CVSTag end) { super(id, Policy.bind("CVSMergeSubscriber.2", start.getName(), end.getName()), Policy.bind("CVSMergeSubscriber.4")); //$NON-NLS-1$ //$NON-NLS-2$ this.start = start; @@ -98,47 +72,44 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour /* (non-Javadoc) * @see org.eclipse.team.internal.ccvs.core.CVSWorkspaceSubscriber#initialize() */ - private void initialize() { + private void initialize() { QualifiedName id = getId(); String syncKeyPrefix = id.getLocalName(); - remoteSynchronizer = new RemoteTagSynchronizer(syncKeyPrefix + end.getName(), end); - baseSynchronizer = new RemoteTagSynchronizer(syncKeyPrefix + start.getName(), start); - mergedSynchronizer = new MergedSynchronizer(syncKeyPrefix + "0merged"); //$NON-NLS-1$ - - try { - setCurrentComparisonCriteria(ContentComparisonCriteria.ID_IGNORE_WS); - } catch (TeamException e) { - // use the default but log an exception because the content comparison should - // always be available. - CVSProviderPlugin.log(e); - } + 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$ ResourcesPlugin.getWorkspace().addResourceChangeListener(this); CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().addListener(this); } - protected SyncInfo getSyncInfo(IResource local, IRemoteResource base, IRemoteResource remote, IProgressMonitor monitor) throws TeamException { - return new CVSMergeSyncInfo(local, base, remote, this, monitor); + protected SyncInfo getSyncInfo(IResource local, IResourceVariant base, IResourceVariant remote) throws TeamException { + CVSMergeSyncInfo info = new CVSMergeSyncInfo(local, base, remote, this); + info.init(); + return info; } public void merged(IResource[] resources) throws TeamException { for (int i = 0; i < resources.length; i++) { IResource resource = resources[i]; - byte[] remoteBytes = remoteSynchronizer.getSyncBytes(resource); - if (remoteBytes == null) { - // If there is no remote, use a place holder to indicate the resouce was merged - remoteBytes = NO_REMOTE; - } - mergedSynchronizer.setSyncBytes(resource, remoteBytes); + internalMerged(resource); } - fireTeamResourceChange(TeamDelta.asSyncChangedDeltas(this, resources)); + fireTeamResourceChange(SubscriberChangeEvent.asSyncChangedDeltas(this, resources)); } + private void internalMerged(IResource resource) throws TeamException { + byte[] remoteBytes = remoteSynchronizer.getBytes(resource); + if (remoteBytes == null) { + mergedSynchronizer.setVariantDoesNotExist(resource); + } else { + mergedSynchronizer.setBytes(resource, remoteBytes); + } + } + /* (non-Javadoc) * @see org.eclipse.team.core.sync.TeamSubscriber#cancel() */ - public void cancel() { - super.cancel(); + public void cancel() { ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); remoteSynchronizer.dispose(); baseSynchronizer.dispose(); @@ -152,25 +123,11 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour return (IResource[]) roots.toArray(new IResource[roots.size()]); } - /* (non-Javadoc) - * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getRemoteSynchronizer() - */ - protected RemoteSynchronizer getRemoteSynchronizer() { - return remoteSynchronizer; - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getBaseSynchronizer() - */ - protected RemoteSynchronizer getBaseSynchronizer() { - return baseSynchronizer; - } - /* (non-Javadoc) * @see org.eclipse.team.core.sync.TeamSubscriber#isSupervised(org.eclipse.core.resources.IResource) */ public boolean isSupervised(IResource resource) throws TeamException { - return getBaseSynchronizer().hasRemote(resource) || getRemoteSynchronizer().hasRemote(resource); + return getBaseSynchronizationCache().getBytes(resource) != null || getRemoteSynchronizationCache().getBytes(resource) != null; } public CVSTag getStartTag() { @@ -180,11 +137,6 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour public CVSTag getEndTag() { return end; } - - public boolean isReleaseSupported() { - // you can't release changes to a merge - return false; - } /* * What to do when a root resource for this merge changes? @@ -231,9 +183,22 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour } } + /** + * Return whether the given resource has been merged with its + * corresponding remote. + * @param resource tghe loca resource + * @return boolean + * @throws TeamException + */ public boolean isMerged(IResource resource) throws TeamException { - return (mergedSynchronizer.getSyncBytes(resource) != null || - mergedSynchronizer.isRemoteKnown(resource)); + byte[] mergedBytes = mergedSynchronizer.getBytes(resource); + byte[] remoteBytes = remoteSynchronizer.getBytes(resource); + if (mergedBytes == null) { + return (remoteBytes == null + && mergedSynchronizer.isVariantKnown(resource) + && remoteSynchronizer.isVariantKnown(resource)); + } + return Util.equals(mergedBytes, remoteBytes); } /* @@ -242,17 +207,126 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour * (non-Javadoc) * @see org.eclipse.team.core.subscribers.ITeamResourceChangeListener#teamResourceChanged(org.eclipse.team.core.subscribers.TeamDelta[]) */ - public void teamResourceChanged(TeamDelta[] deltas) { + public void subscriberResourceChanged(ISubscriberChangeEvent[] deltas) { for (int i = 0; i < deltas.length; i++) { - TeamDelta delta = deltas[i]; + ISubscriberChangeEvent delta = deltas[i]; switch(delta.getFlags()) { - case TeamDelta.PROVIDER_DECONFIGURED: + case ISubscriberChangeEvent.ROOT_REMOVED: IResource resource = delta.getResource(); if(roots.remove(resource)) { - fireTeamResourceChange(new TeamDelta[] {delta}); + fireTeamResourceChange(new ISubscriberChangeEvent[] {delta}); } break; } } - } + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getRemoteTag() + */ + protected CVSTag getRemoteTag() { + return getEndTag(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getBaseTag() + */ + protected CVSTag getBaseTag() { + return getStartTag(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getBaseSynchronizationCache() + */ + protected ResourceVariantTree getBaseSynchronizationCache() { + return baseSynchronizer; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getRemoteSynchronizationCache() + */ + protected ResourceVariantTree getRemoteSynchronizationCache() { + return remoteSynchronizer; + } + + protected boolean getCacheFileContentsHint() { + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#refreshBase(org.eclipse.core.resources.IResource[], int, org.eclipse.core.runtime.IProgressMonitor) + */ + protected IResource[] refreshBase(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException { + // Only refresh the base of a resource once as it should not change + List unrefreshed = new ArrayList(); + for (int i = 0; i < resources.length; i++) { + IResource resource = resources[i]; + if (!baseSynchronizer.isVariantKnown(resource)) { + unrefreshed.add(resource); + } + } + if (unrefreshed.isEmpty()) { + monitor.done(); + return new IResource[0]; + } + IResource[] refreshed = super.refreshBase((IResource[]) unrefreshed.toArray(new IResource[unrefreshed.size()]), depth, monitor); + return refreshed; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#refreshRemote(org.eclipse.core.resources.IResource[], int, org.eclipse.core.runtime.IProgressMonitor) + */ + protected IResource[] refreshRemote(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException { + monitor.beginTask(null, 100); + try { + IResource[] refreshed = super.refreshRemote(resources, depth, Policy.subMonitorFor(monitor, 50)); + compareWithRemote(refreshed, Policy.subMonitorFor(monitor, 50)); + return refreshed; + } finally { + monitor.done(); + } + } + + /* + * Mark as merged any local resources whose contents match that of the remote resource. + */ + private void compareWithRemote(IResource[] refreshed, IProgressMonitor monitor) throws CVSException, TeamException { + // For any remote changes, if the revision differs from the local, compare the contents. + if (refreshed.length == 0) return; + SyncInfoFilter.ContentComparisonSyncInfoFilter contentFilter = + new SyncInfoFilter.ContentComparisonSyncInfoFilter(); + monitor.beginTask(null, refreshed.length * 100); + for (int i = 0; i < refreshed.length; i++) { + IResource resource = refreshed[i]; + if (resource.getType() == IResource.FILE) { + ICVSFile local = CVSWorkspaceRoot.getCVSFileFor((IFile)resource); + byte[] localBytes = local.getSyncBytes(); + byte[] remoteBytes = remoteSynchronizer.getBytes(resource); + if (remoteBytes != null + && localBytes != null + && local.exists() + && !ResourceSyncInfo.getRevision(remoteBytes).equals(ResourceSyncInfo.getRevision(localBytes)) + && contentFilter.select(getSyncInfo(resource), Policy.subMonitorFor(monitor, 100))) { + // The contents are equals so mark the file as merged + internalMerged(resource); + } + } + } + monitor.done(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.utils.SyncTreeSubscriber#getBaseResource(org.eclipse.core.resources.IResource) + */ + public IResourceVariant getBaseResource(IResource resource) throws TeamException { + // 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()); + if (parentBytes != null) { + return RemoteFile.fromBytes(resource, mergedBytes, parentBytes); + } + } + return super.getBaseResource(resource); + } } \ No newline at end of file diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSMergeSyncInfo.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSMergeSyncInfo.java index f70525146..b4a4d0feb 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSMergeSyncInfo.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSMergeSyncInfo.java @@ -9,9 +9,8 @@ package org.eclipse.team.internal.ccvs.core; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.*; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.core.subscribers.TeamSubscriber; -import org.eclipse.team.core.sync.IRemoteResource; +import org.eclipse.team.core.subscribers.*; +import org.eclipse.team.core.synchronize.*; /** * @author JLemieux @@ -21,6 +20,10 @@ import org.eclipse.team.core.sync.IRemoteResource; */ public class CVSMergeSyncInfo extends CVSSyncInfo { + public CVSMergeSyncInfo(IResource local, IResourceVariant base, IResourceVariant remote, Subscriber subscriber) { + super(local, base, remote, subscriber); + } + /* (non-Javadoc) * @see org.eclipse.team.internal.ccvs.core.CVSSyncInfo#handleDeletionConflicts(int) */ @@ -32,13 +35,13 @@ public class CVSMergeSyncInfo extends CVSSyncInfo { return kind; } - protected int calculateKind(IProgressMonitor progress) throws TeamException { + protected int calculateKind() throws TeamException { // Report merged resources as in-sync if (((CVSMergeSubscriber)getSubscriber()).isMerged(getLocal())) { return IN_SYNC; } - int kind = super.calculateKind(progress); + int kind = super.calculateKind(); // Report outgoing resources as in-sync if((kind & DIRECTION_MASK) == OUTGOING) { @@ -47,10 +50,6 @@ public class CVSMergeSyncInfo extends CVSSyncInfo { return kind; } - - public CVSMergeSyncInfo(IResource local, IRemoteResource base, IRemoteResource remote, TeamSubscriber subscriber, IProgressMonitor monitor) throws TeamException { - super(local, base, remote, subscriber, monitor); - } /* (non-Javadoc) * @see org.eclipse.team.internal.ccvs.core.CVSSyncInfo#makeOutgoing(org.eclipse.core.runtime.IProgressMonitor) diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSProviderPlugin.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSProviderPlugin.java index a51e39ed3..e938860e2 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSProviderPlugin.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSProviderPlugin.java @@ -10,35 +10,12 @@ *******************************************************************************/ package org.eclipse.team.internal.ccvs.core; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResourceChangeEvent; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IPluginDescriptor; -import org.eclipse.core.runtime.ISafeRunnable; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Plugin; -import org.eclipse.core.runtime.Preferences; -import org.eclipse.core.runtime.QualifiedName; -import org.eclipse.core.runtime.Status; -import org.eclipse.team.core.RepositoryProvider; -import org.eclipse.team.core.Team; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.RemoteContentsCache; +import java.io.*; +import java.util.*; + +import org.eclipse.core.resources.*; +import org.eclipse.core.runtime.*; +import org.eclipse.team.core.*; import org.eclipse.team.internal.ccvs.core.client.Command; import org.eclipse.team.internal.ccvs.core.client.Command.KSubstOption; import org.eclipse.team.internal.ccvs.core.client.Command.QuietOption; @@ -47,10 +24,7 @@ import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation; import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; import org.eclipse.team.internal.ccvs.core.resources.FileModificationManager; import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo; -import org.eclipse.team.internal.ccvs.core.util.BuildCleanupListener; -import org.eclipse.team.internal.ccvs.core.util.KnownRepositories; -import org.eclipse.team.internal.ccvs.core.util.SyncFileChangeListener; -import org.eclipse.team.internal.ccvs.core.util.Util; +import org.eclipse.team.internal.ccvs.core.util.*; public class CVSProviderPlugin extends Plugin { @@ -79,7 +53,7 @@ public class CVSProviderPlugin extends Plugin { // cvs plugin extension points and ids public static final String ID = "org.eclipse.team.cvs.core"; //$NON-NLS-1$ - public static final QualifiedName CVS_WORKSPACE_SUBSCRIBER_ID = new QualifiedName("org.eclipse.team.cvs.ui.cvsworkspace-participant", "syncparticipant"); //$NON-NLS-1$ + public static final QualifiedName CVS_WORKSPACE_SUBSCRIBER_ID = new QualifiedName("org.eclipse.team.cvs.ui.cvsworkspace-participant", "syncparticipant"); //$NON-NLS-1$ //$NON-NLS-2$ public static final String PT_AUTHENTICATOR = "authenticator"; //$NON-NLS-1$ public static final String PT_CONNECTIONMETHODS = "connectionmethods"; //$NON-NLS-1$ public static final String PT_FILE_MODIFICATION_VALIDATOR = "filemodificationvalidator"; //$NON-NLS-1$ @@ -321,8 +295,6 @@ public class CVSProviderPlugin extends Plugin { workspace.addResourceChangeListener(fileModificationManager, IResourceChangeEvent.POST_CHANGE); fileModificationManager.registerSaveParticipant(); - RemoteContentsCache.enableCaching(ID); - getCVSWorkspaceSubscriber(); } @@ -346,8 +318,6 @@ public class CVSProviderPlugin extends Plugin { // each class that added itself as a participant to have to listen to shutdown. workspace.removeSaveParticipant(this); - RemoteContentsCache.disableCache(ID); - deleteCrashFile(); } @@ -761,7 +731,4 @@ public class CVSProviderPlugin extends Plugin { return crash; } - public RemoteContentsCache getRemoteContentsCache() { - return RemoteContentsCache.getCache(CVSProviderPlugin.ID); - } } diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSRevisionNumberCompareCriteria.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSRevisionNumberCompareCriteria.java index fef08e05f..519be9459 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSRevisionNumberCompareCriteria.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSRevisionNumberCompareCriteria.java @@ -12,48 +12,38 @@ package org.eclipse.team.internal.ccvs.core; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.subscribers.ComparisonCriteria; -import org.eclipse.team.core.sync.IRemoteResource; +import org.eclipse.team.core.synchronize.IResourceVariant; +import org.eclipse.team.core.synchronize.IResourceVariantComparator; import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; -import org.eclipse.team.internal.ccvs.core.Policy; /** * CVSRevisionNumberCompareCriteria */ - public class CVSRevisionNumberCompareCriteria extends ComparisonCriteria { + public class CVSRevisionNumberCompareCriteria implements IResourceVariantComparator { + + private CVSSyncTreeSubscriber subscriber; - /* (non-Javadoc) - * @see ComparisonCriteria#getName() - */ - public String getName() { - return Policy.bind("CVSRevisionNumberCompareCriteria.1"); //$NON-NLS-1$ - } - - /* (non-Javadoc) - * @see ComparisonCriteria#getId() - */ - public String getId() { - return "org.eclipse.team.cvs.revisioncomparator"; //$NON-NLS-1$ + public CVSRevisionNumberCompareCriteria(CVSSyncTreeSubscriber subscriber) { + this.subscriber = subscriber; } /* (non-Javadoc) * @see ComparisonCriteria#compare(Object, Object, IProgressMonitor) */ - public boolean compare(Object e1, Object e2, IProgressMonitor monitor) { - if(e1 instanceof IResource && e2 instanceof IRemoteResource) { - return compare((IResource)e1, (IRemoteResource)e2); - } else if(e1 instanceof IRemoteResource && e2 instanceof IRemoteResource) { - return compare((IRemoteResource)e1, (IRemoteResource)e2); + public boolean compare(Object e1, Object e2) { + if(e1 instanceof IResource && e2 instanceof ICVSRemoteResource) { + return compare((IResource)e1, (ICVSRemoteResource)e2); + } else if(e1 instanceof ICVSRemoteResource && e2 instanceof ICVSRemoteResource) { + return compare((ICVSRemoteResource)e1, (ICVSRemoteResource)e2); } return false; } /** - * @see RemoteSyncElement#timestampEquals(IRemoteResource, IRemoteResource) + * @see RemoteSyncElement#timestampEquals(IResourceVariant, IResourceVariant) */ - protected boolean compare(IRemoteResource e1, IRemoteResource e2) { + protected boolean compare(ICVSRemoteResource e1, ICVSRemoteResource e2) { if(e1.isContainer()) { if(e2.isContainer()) { return true; @@ -64,9 +54,9 @@ import org.eclipse.team.internal.ccvs.core.Policy; } /** - * @see RemoteSyncElement#timestampEquals(IResource, IRemoteResource) + * @see RemoteSyncElement#timestampEquals(IResource, IResourceVariant) */ - protected boolean compare(IResource e1, IRemoteResource e2) { + protected boolean compare(IResource e1, ICVSRemoteResource e2) { if(e1.getType() != IResource.FILE) { if(e2.isContainer()) { return true; @@ -92,9 +82,23 @@ import org.eclipse.team.internal.ccvs.core.Policy; } /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.ComparisonCriteria#usesFileContents() + * @see org.eclipse.team.core.subscribers.IComparisonCriteria#compare(org.eclipse.core.resources.IResource, org.eclipse.team.core.subscribers.ISubscriberResource) */ - public boolean usesFileContents() { - return false; + public boolean compare(IResource local, IResourceVariant remote) { + return compare(local, (ICVSRemoteResource)remote); + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.IComparisonCriteria#compare(org.eclipse.team.core.subscribers.ISubscriberResource, org.eclipse.team.core.subscribers.ISubscriberResource) + */ + public boolean compare(IResourceVariant base, IResourceVariant remote) { + return compare((ICVSRemoteResource)base, (ICVSRemoteResource)remote); + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.ISubscriberResourceComparator#isThreeWay() + */ + public boolean isThreeWay() { + return subscriber.isThreeWay(); } } diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSSyncInfo.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSSyncInfo.java index 74209bae2..5f06cdb1e 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSSyncInfo.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSSyncInfo.java @@ -15,14 +15,14 @@ import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.core.subscribers.TeamSubscriber; -import org.eclipse.team.core.sync.IRemoteResource; +import org.eclipse.team.core.subscribers.*; +import org.eclipse.team.core.synchronize.*; import org.eclipse.team.internal.ccvs.core.client.Update; import org.eclipse.team.internal.ccvs.core.resources.*; import org.eclipse.team.internal.ccvs.core.syncinfo.*; import org.eclipse.team.internal.ccvs.core.util.Assert; import org.eclipse.team.internal.ccvs.core.Policy; +import org.eclipse.team.internal.core.subscribers.caches.SyncTreeSubscriber; /** * CVSSyncInfo @@ -37,20 +37,26 @@ public class CVSSyncInfo extends SyncInfo { private static final int PARENT_NOT_MANAGED = 3; private static final int REMOTE_DOES_NOT_EXIST = 4; private static final int SYNC_INFO_CONFLICTS = 5; + private Subscriber subscriber; - public CVSSyncInfo(IResource local, IRemoteResource base, IRemoteResource remote, TeamSubscriber subscriber, IProgressMonitor monitor) throws TeamException { - super(local, base, remote, subscriber, monitor); + public CVSSyncInfo(IResource local, IResourceVariant base, IResourceVariant remote, Subscriber subscriber) { + super(local, base, remote, ((SyncTreeSubscriber)subscriber).getResourceComparator()); + this.subscriber = subscriber; } + public Subscriber getSubscriber() { + return subscriber; + } + /* (non-Javadoc) * @see org.eclipse.team.core.sync.SyncInfo#computeSyncKind(org.eclipse.core.runtime.IProgressMonitor) */ - protected int calculateKind(IProgressMonitor progress) throws TeamException { + protected int calculateKind() throws TeamException { // special handling for folders, the generic sync algorithm doesn't work well // with CVS because folders are not in namespaces (e.g. they exist in all versions // and branches). IResource local = getLocal(); - if(local.getType() != IResource.FILE && getSubscriber().isThreeWay()) { + if(local.getType() != IResource.FILE) { int folderKind = SyncInfo.IN_SYNC; ICVSRemoteFolder remote = (ICVSRemoteFolder)getRemote(); ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor((IContainer)local); @@ -93,11 +99,11 @@ public class CVSSyncInfo extends SyncInfo { // 1. Run the generic sync calculation algorithm, then handle CVS specific // sync cases. - int kind = super.calculateKind(progress); + int kind = super.calculateKind(); // 2. Set the CVS specific sync type based on the workspace sync state provided // by the CVS server. - IRemoteResource remote = getRemote(); + IResourceVariant remote = getRemote(); if(remote!=null && (kind & SyncInfo.PSEUDO_CONFLICT) == 0) { RemoteResource cvsRemote = (RemoteResource)remote; int type = cvsRemote.getWorkspaceSyncState(); @@ -191,11 +197,15 @@ public class CVSSyncInfo extends SyncInfo { // We have a conflicting change, Update the local revision info.setRevision(remote.getSyncInfo().getRevision()); } else { - // We have conflictin additions. - // We need to fetch the contents of the remote to get all the relevant information (timestamp, permissions) - // The most important thing we get is the keyword substitution mode which must be right to perform the commit - remote.getContents(Policy.monitorFor(monitor)); - info = remote.getSyncInfo().cloneMutable(); + try { + // We have conflictin additions. + // We need to fetch the contents of the remote to get all the relevant information (timestamp, permissions) + // The most important thing we get is the keyword substitution mode which must be right to perform the commit + remote.getStorage(Policy.monitorFor(monitor)).getContents(); + info = remote.getSyncInfo().cloneMutable(); + } catch (CoreException e) { + TeamException.asTeamException(e); + } } } else if (getBase() != null) { // We have a remote deletion. Make the local an addition @@ -317,8 +327,8 @@ public class CVSSyncInfo extends SyncInfo { } public String toString() { - IRemoteResource base = getBase(); - IRemoteResource remote = getRemote(); + IResourceVariant base = getBase(); + IResourceVariant remote = getRemote(); StringBuffer result = new StringBuffer(super.toString()); result.append("Local: "); //$NON-NLS-1$ result.append(getLocal().toString()); 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 fce0d5a2f..2cb785bd7 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,82 +10,37 @@ *******************************************************************************/ package org.eclipse.team.internal.ccvs.core; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; -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.core.resources.*; +import org.eclipse.core.runtime.*; import org.eclipse.team.core.RepositoryProvider; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.ComparisonCriteria; -import org.eclipse.team.core.subscribers.ContentComparisonCriteria; -import org.eclipse.team.core.subscribers.RemoteSynchronizer; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.core.subscribers.TeamSubscriber; -import org.eclipse.team.core.subscribers.TeamDelta; -import org.eclipse.team.core.sync.IRemoteResource; -import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; -import org.eclipse.team.internal.ccvs.core.Policy; +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.*; /** * This class provides common funtionality for three way sychronizing * for CVS. */ -public abstract class CVSSyncTreeSubscriber extends TeamSubscriber { +public abstract class CVSSyncTreeSubscriber extends SyncTreeSubscriber { + + public static final String SYNC_KEY_QUALIFIER = "org.eclipse.team.cvs"; //$NON-NLS-1$ + + private IResourceVariantComparator comparisonCriteria; private QualifiedName id; private String name; private String description; - // options this subscriber supports for determining the sync state of resources - private Map comparisonCriterias = new HashMap(); - private String defaultCriteria; - CVSSyncTreeSubscriber(QualifiedName id, String name, String description) { this.id = id; this.name = name; this.description = description; - initializeComparisonCriteria(); - } - - /** - * Method invoked from the constructor to initialize the comparison criteria - * and the default criteria. - * This method can be overriden by subclasses. - */ - protected void initializeComparisonCriteria() { - // setup comparison criteria - ComparisonCriteria revisionNumberComparator = new CVSRevisionNumberCompareCriteria(); - ComparisonCriteria contentsComparator = new ContentComparisonCriteria(new ComparisonCriteria[] {revisionNumberComparator}, false /*consider whitespace */); - ComparisonCriteria contentsComparatorIgnoreWhitespace = new ContentComparisonCriteria(new ComparisonCriteria[] {revisionNumberComparator}, true /* ignore whitespace */); - - addComparisonCriteria(revisionNumberComparator); - addComparisonCriteria(contentsComparator); - addComparisonCriteria(contentsComparatorIgnoreWhitespace); - - // default - defaultCriteria = revisionNumberComparator.getId(); - } - - /** - * Add the comparison criteria to the subscriber - * - * @param comparator - */ - protected void addComparisonCriteria(ComparisonCriteria comparator) { - comparisonCriterias.put(comparator.getId(), comparator); + this.comparisonCriteria = new CVSRevisionNumberCompareCriteria(this); } /* (non-Javadoc) @@ -109,90 +64,23 @@ public abstract class CVSSyncTreeSubscriber extends TeamSubscriber { return description; } - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.TeamSubscriber#members(org.eclipse.core.resources.IResource) - */ - public IResource[] members(IResource resource) throws TeamException { - if(resource.getType() == IResource.FILE) { - return new IResource[0]; - } - try { - // Filter and return only phantoms associated with the remote synchronizer. - IResource[] members; - try { - members = ((IContainer)resource).members(true /* include phantoms */); - } 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 - // so ignore the exception and return that there are no members - return new IResource[0]; - } - throw e; - } - List filteredMembers = new ArrayList(members.length); - for (int i = 0; i < members.length; i++) { - IResource member = members[i]; - - // TODO: consider that there may be several sync states on this resource. There - // should instead be a method to check for the existance of a set of sync types on - // a resource. - if(member.isPhantom() && !getRemoteSynchronizer().hasRemote(member)) { - continue; - } - - // TODO: Is this a valid use of isSupervised - if (isSupervised(resource)) { - filteredMembers.add(member); - } - } - return (IResource[]) filteredMembers.toArray(new IResource[filteredMembers.size()]); - } catch (CoreException e) { - throw CVSException.wrapException(e); - } - - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.TeamSubscriber#roots() - */ - public IResource[] roots() { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.ISyncTreeSubscriber#getRemoteResource(org.eclipse.core.resources.IResource) - */ - public IRemoteResource getRemoteResource(IResource resource) throws TeamException { - return getRemoteSynchronizer().getRemoteResource(resource); - } - - public IRemoteResource getBaseResource(IResource resource) throws TeamException { - return getBaseSynchronizer().getRemoteResource(resource); - } - - /** - * Return the synchronizer that provides the remote resources - */ - protected abstract RemoteSynchronizer getRemoteSynchronizer(); - /** - * Return the synchronizer that provides the base resources - */ - protected abstract RemoteSynchronizer getBaseSynchronizer(); - /* (non-Javadoc) * @see org.eclipse.team.core.sync.ISyncTreeSubscriber#getSyncInfo(org.eclipse.core.resources.IResource) */ - public SyncInfo getSyncInfo(IResource resource, IProgressMonitor monitor) throws TeamException { + public SyncInfo getSyncInfo(IResource resource) throws TeamException { if (!isSupervised(resource)) return null; - IRemoteResource remoteResource = getRemoteResource(resource); - if(resource.getType() == IResource.FILE) { - IRemoteResource baseResource = getBaseResource(resource); - return getSyncInfo(resource, baseResource, remoteResource, monitor); + if(resource.getType() == IResource.FILE || !isThreeWay()) { + return super.getSyncInfo(resource); } else { // In CVS, folders do not have a base. Hence, the remote is used as the base. - return getSyncInfo(resource, remoteResource, remoteResource, monitor); + IResourceVariant remoteResource = getRemoteResource(resource); + return getSyncInfo(resource, remoteResource, remoteResource); } } + + protected boolean isThreeWay() { + return true; + } /** * Method that creates an instance of SyncInfo for the provider local, base and remote. @@ -203,20 +91,10 @@ public abstract class CVSSyncTreeSubscriber extends TeamSubscriber { * @param monitor * @return */ - protected SyncInfo getSyncInfo(IResource local, IRemoteResource base, IRemoteResource remote, IProgressMonitor monitor) throws TeamException { - try { - monitor = Policy.monitorFor(monitor); - monitor.beginTask(null, 100); - CVSSyncInfo info = new CVSSyncInfo(local, base, remote, this, Policy.subMonitorFor(monitor, 100)); - - // if it's out of sync, then cache the contents - //if(info.getKind() != SyncInfo.IN_SYNC && remote != null) { - // remote.getContents(Policy.subMonitorFor(monitor, 30)); - //} - return info; - } finally { - monitor.done(); - } + protected SyncInfo getSyncInfo(IResource local, IResourceVariant base, IResourceVariant remote) throws TeamException { + CVSSyncInfo info = new CVSSyncInfo(local, base, remote, this); + info.init(); + return info; } /* (non-Javadoc) @@ -248,17 +126,17 @@ public abstract class CVSSyncTreeSubscriber extends TeamSubscriber { monitor = Policy.monitorFor(monitor); try { // Take a guess at the work involved for refreshing the base and remote tree - int baseWork = getCacheFileContentsHint() ? 10 : 30; + int baseWork = isThreeWay() ? (getCacheFileContentsHint() ? 30 : 10) : 0; int remoteWork = 100; monitor.beginTask(null, baseWork + remoteWork); - IResource[] baseChanges = refreshBase(resource, depth, Policy.subMonitorFor(monitor, baseWork)); - IResource[] remoteChanges = refreshRemote(resource, depth, Policy.subMonitorFor(monitor, remoteWork)); + IResource[] baseChanges = refreshBase(new IResource[] {resource}, depth, Policy.subMonitorFor(monitor, baseWork)); + IResource[] remoteChanges = refreshRemote(new IResource[] {resource}, depth, Policy.subMonitorFor(monitor, remoteWork)); Set allChanges = new HashSet(); allChanges.addAll(Arrays.asList(remoteChanges)); allChanges.addAll(Arrays.asList(baseChanges)); IResource[] changedResources = (IResource[]) allChanges.toArray(new IResource[allChanges.size()]); - fireTeamResourceChange(TeamDelta.asSyncChangedDeltas(this, changedResources)); + fireTeamResourceChange(SubscriberChangeEvent.asSyncChangedDeltas(this, changedResources)); return Status.OK_STATUS; } catch (TeamException e) { return new CVSStatus(IStatus.ERROR, Policy.bind("CVSSyncTreeSubscriber.2", resource.getFullPath().toString(), e.getMessage()), e); //$NON-NLS-1$ @@ -266,41 +144,34 @@ public abstract class CVSSyncTreeSubscriber extends TeamSubscriber { monitor.done(); } } - protected IResource[] refreshBase(IResource resource, int depth, IProgressMonitor monitor) throws TeamException { - return getBaseSynchronizer().refresh(resource, depth, getCacheFileContentsHint(), monitor); + + protected boolean getCacheFileContentsHint() { + return false; } - protected IResource[] refreshRemote(IResource resource, int depth, IProgressMonitor monitor) throws TeamException { - return getRemoteSynchronizer().refresh(resource, depth, getCacheFileContentsHint(), monitor); + protected IResource[] refreshBase(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException { + if (isThreeWay()) { + return new CVSRefreshOperation(getBaseSynchronizationCache(), null, getBaseTag(), getCacheFileContentsHint()) + .refresh(resources, depth, monitor); + } else { + return new IResource[0]; + } } - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.ISyncTreeSubscriber#getCurrentComparisonCriteria() - */ - public ComparisonCriteria getCurrentComparisonCriteria() { - return (ComparisonCriteria)comparisonCriterias.get(defaultCriteria); + protected IResource[] refreshRemote(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException { + return new CVSRefreshOperation(getRemoteSynchronizationCache(), getBaseSynchronizationCache(), getRemoteTag(), getCacheFileContentsHint()) + .refresh(resources, depth, monitor); } - private boolean getCacheFileContentsHint() { - return getCurrentComparisonCriteria().usesFileContents(); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.ISyncTreeSubscriber#setCurrentComparisonCriteria(java.lang.String) + /** + * Return the tag associated with the base tree. t is used by the refreshBase method. */ - public void setCurrentComparisonCriteria(String id) throws TeamException { - if(! comparisonCriterias.containsKey(id)) { - throw new CVSException(Policy.bind("CVSSyncTreeSubscriber.0", id, getName())); //$NON-NLS-1$ - } - this.defaultCriteria = id; - } + protected abstract CVSTag getRemoteTag(); - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.ISyncTreeSubscriber#getComparisonCriterias() + /** + * Return the tag associated with the base tree. t is used by the refreshRemote method. */ - public ComparisonCriteria[] getComparisonCriterias() { - return (ComparisonCriteria[]) comparisonCriterias.values().toArray(new ComparisonCriteria[comparisonCriterias.size()]); - } + protected abstract CVSTag getBaseTag(); /* (non-Javadoc) * @see org.eclipse.team.core.sync.ISyncTreeSubscriber#isSupervised(org.eclipse.core.resources.IResource) @@ -314,7 +185,7 @@ public abstract class CVSSyncTreeSubscriber extends TeamSubscriber { ICVSResource cvsThing = CVSWorkspaceRoot.getCVSResourceFor(resource); if (cvsThing.isIgnored()) { // An ignored resource could have an incoming addition (conflict) - return getRemoteSynchronizer().hasRemote(resource); + return hasRemote(resource); } return true; } catch (TeamException e) { @@ -327,24 +198,137 @@ public abstract class CVSSyncTreeSubscriber extends TeamSubscriber { } } - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.TeamSubscriber#isThreeWay() + public IResourceVariant getRemoteResource(IResource resource) throws TeamException { + return getRemoteResource(resource, getRemoteSynchronizationCache()); + } + + public IResourceVariant getBaseResource(IResource resource) throws TeamException { + if (isThreeWay()) { + return getRemoteResource(resource, getBaseSynchronizationCache()); + } else { + return null; + } + } + + /** + * Return the synchronization cache that provides access to the base sychronization bytes. */ - public boolean isThreeWay() { - return true; + protected abstract ResourceVariantTree getBaseSynchronizationCache(); + + /** + * Return the synchronization cache that provides access to the base sychronization bytes. + */ + protected abstract ResourceVariantTree getRemoteSynchronizationCache(); + + protected IResourceVariant getRemoteResource(IResource resource, ResourceVariantTree 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); + } + } + } + + private String getSyncName(ResourceVariantTree cache) { + if (cache instanceof PersistantResourceVariantTree) { + return ((PersistantResourceVariantTree)cache).getSyncName().toString(); + } + return cache.getClass().getName(); } /* (non-Javadoc) - * @see org.eclipse.team.core.sync.TeamSubscriber#isCancellable() + * @see org.eclipse.team.core.subscribers.helpers.SyncTreeSubscriber#hasRemote(org.eclipse.core.resources.IResource) */ - public boolean isCancellable() { - return false; + protected boolean hasRemote(IResource resource) throws TeamException { + return getRemoteSynchronizationCache().getBytes(resource) != null; } /* (non-Javadoc) - * @see org.eclipse.team.core.sync.TeamSubscriber#cancel() + * @see org.eclipse.team.core.subscribers.TeamSubscriber#getDefaultComparisonCriteria() */ - public void cancel() { - // noop + public IResourceVariantComparator getResourceComparator() { + return comparisonCriteria; + } + + public IResource[] members(IResource resource) throws TeamException { + if(resource.getType() == IResource.FILE) { + return new IResource[0]; + } + try { + Set allMembers = new HashSet(); + try { + allMembers.addAll(Arrays.asList(((IContainer)resource).members())); + } catch (CoreException e) { + if (e.getStatus().getCode() == IResourceStatus.RESOURCE_NOT_FOUND) { + // The resource is no longer exists so ignore the exception + } else { + throw e; + } + } + allMembers.addAll(Arrays.asList(getMembers(getRemoteSynchronizationCache(), resource))); + if (isThreeWay()) { + allMembers.addAll(Arrays.asList(getMembers(getBaseSynchronizationCache(), resource))); + } + for (Iterator iterator = allMembers.iterator(); iterator.hasNext();) { + IResource member = (IResource) iterator.next(); + if(!member.exists() && !hasRemote(member)) { + // Remove deletion conflicts + iterator.remove(); + } else if (!isSupervised(resource)) { + // Remove unsupervised resources + iterator.remove(); + } + } + return (IResource[]) allMembers.toArray(new IResource[allMembers.size()]); + } catch (CoreException e) { + throw TeamException.asTeamException(e); + } + } + + private IResource[] getMembers(ResourceVariantTree cache, IResource resource) throws TeamException, CoreException { + // Filter and return only phantoms associated with the remote synchronizer. + IResource[] members; + try { + members = cache.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 + // so ignore the exception and return that there are no members + return new IResource[0]; + } + throw e; + } + return members; } } diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java index 223b1d1a4..8bc156e6a 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java @@ -19,14 +19,14 @@ import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.Status; import org.eclipse.team.core.RepositoryProvider; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.IRemoteSyncElement; import org.eclipse.team.internal.ccvs.core.client.*; import org.eclipse.team.internal.ccvs.core.client.Command.KSubstOption; import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption; import org.eclipse.team.internal.ccvs.core.client.listeners.*; import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation; import org.eclipse.team.internal.ccvs.core.connection.CVSServerException; -import org.eclipse.team.internal.ccvs.core.resources.*; +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.*; import org.eclipse.team.internal.core.streams.CRLFtoLFInputStream; @@ -676,19 +676,6 @@ public class CVSTeamProvider extends RepositoryProvider { } } - /** - * Update the sync info of the local resource associated with the sync element such that - * the revision of the local resource matches that of the remote resource. - * This will allow commits on the local resource to succeed. - * - * Only file resources can be merged. - */ - public void merged(IRemoteSyncElement[] elements) throws TeamException { - for (int i=0;inull if progress reporting is not required. + */ + public InputStream getContents(IProgressMonitor progress) throws TeamException; + /** * Get the log entry for the revision the remote file represents. * This method will return null until after the getContents(IProgressMonitor) diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSRemoteResource.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSRemoteResource.java index c69a64eff..0bff56d04 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSRemoteResource.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSRemoteResource.java @@ -11,10 +11,8 @@ package org.eclipse.team.internal.ccvs.core; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.*; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.IRemoteResource; import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption; /** @@ -24,7 +22,15 @@ import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption; * * Clients are not expected to implement this interface. */ -public interface ICVSRemoteResource extends IRemoteResource, ICVSResource { +public interface ICVSRemoteResource extends ICVSResource, IAdaptable { + + /** + * Answers if the remote element may have children. + * + * @return true if the remote element may have children and + * false otherwise. + */ + public boolean isContainer(); /** * Return the repository @@ -71,5 +77,12 @@ public interface ICVSRemoteResource extends IRemoteResource, ICVSResource { * Tag the remote resources referenced by the receiver (using rtag) */ public IStatus tag(CVSTag tag, LocalOption[] localOptions, IProgressMonitor monitor) throws CVSException; + + /** + * TODO: Temporary + * @param progress + * @return + */ + public ICVSRemoteResource[] members(IProgressMonitor progress) throws TeamException; } diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/listeners/AnnotateListener.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/listeners/AnnotateListener.java index 0f45fbc90..205bc93f2 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/listeners/AnnotateListener.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/listeners/AnnotateListener.java @@ -18,6 +18,7 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.core.client.CommandOutputListener; +import org.eclipse.team.internal.ccvs.core.Policy; public class AnnotateListener extends CommandOutputListener { @@ -89,8 +90,8 @@ public class AnnotateListener extends CommandOutputListener { * @see org.eclipse.team.internal.ccvs.core.client.listeners.ICommandOutputListener#errorLine(java.lang.String, org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation, org.eclipse.team.internal.ccvs.core.ICVSFolder, org.eclipse.core.runtime.IProgressMonitor) */ public IStatus errorLine(String line, ICVSRepositoryLocation location, ICVSFolder commandRoot, IProgressMonitor monitor) { - if(line.startsWith("Skipping binary file")) { - error = "Cannot annotate a binary file."; + if(line.startsWith(Policy.bind("AnnotateListener.3"))) { //$NON-NLS-1$ + error = Policy.bind("AnnotateListener.4"); //$NON-NLS-1$ return new CVSStatus(CVSStatus.ERROR, CVSStatus.SERVER_ERROR, commandRoot, error); } return super.errorLine(line, location, commandRoot, monitor); diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/listeners/CompareDiffListener.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/listeners/CompareDiffListener.java index 02e448576..cb898cbd6 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/listeners/CompareDiffListener.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/listeners/CompareDiffListener.java @@ -20,6 +20,7 @@ import org.eclipse.team.internal.ccvs.core.CVSStatus; import org.eclipse.team.internal.ccvs.core.ICVSFolder; import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation; import org.eclipse.team.internal.ccvs.core.client.CommandOutputListener; +import org.eclipse.team.internal.ccvs.core.Policy; /** * This class interprets the output of "cvs diff --brief ..." in order to get the revisions @@ -34,11 +35,11 @@ public class CompareDiffListener extends CommandOutputListener { static { try { LOCAL_FILE_MATCHER = new ServerMessageLineMatcher( - "Index: (localFile:.*:localFile)", new String[] {"localFile"}); + "Index: (localFile:.*:localFile)", new String[] {"localFile"}); //$NON-NLS-1$ //$NON-NLS-2$ REMOTE_FILE_MATCHER = new ServerMessageLineMatcher( - "RCS file: (remoteFile:.*:remoteFile),v", new String[] {"remoteFile"}); + "RCS file: (remoteFile:.*:remoteFile),v", new String[] {"remoteFile"}); //$NON-NLS-1$ //$NON-NLS-2$ REVISION_LINE_MATCHER = new ServerMessageLineMatcher( - "diff .* -r(leftRevision:.*:leftRevision) -r(rightRevision:.*:rightRevision)", new String[] {"leftRevision", "rightRevision"}); + "diff .* -r(leftRevision:.*:leftRevision) -r(rightRevision:.*:rightRevision)", new String[] {"leftRevision", "rightRevision"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } catch (CVSException e) { // This is serious as the listener will not function properly CVSProviderPlugin.log(e); @@ -75,20 +76,20 @@ public class CompareDiffListener extends CommandOutputListener { } Map map = LOCAL_FILE_MATCHER.processServerMessage(line); if (map != null) { - localFilePath = (String)map.get("localFile"); + localFilePath = (String)map.get("localFile"); //$NON-NLS-1$ return OK; } map = REMOTE_FILE_MATCHER.processServerMessage(line); if (map != null) { - remoteFilePath = (String)map.get("remoteFile"); + remoteFilePath = (String)map.get("remoteFile"); //$NON-NLS-1$ return OK; } map = REVISION_LINE_MATCHER.processServerMessage(line); if (map != null) { - leftRevision = (String)map.get("leftRevision"); - rightRevision = (String)map.get("rightRevision"); + leftRevision = (String)map.get("leftRevision"); //$NON-NLS-1$ + rightRevision = (String)map.get("rightRevision"); //$NON-NLS-1$ if (localFilePath == null || remoteFilePath == null) { - return new CVSStatus(IStatus.ERROR, "Unsupported message sequence received while comparing using CVS diff command"); + return new CVSStatus(IStatus.ERROR, Policy.bind("CompareDiffListener.11")); //$NON-NLS-1$ } listener.fileDiff(localFilePath, remoteFilePath, leftRevision, rightRevision); localFilePath = remoteFilePath = leftRevision = rightRevision = null; @@ -99,7 +100,7 @@ public class CompareDiffListener extends CommandOutputListener { } private IStatus handleUnknownDiffFormat(String line) { - return new CVSStatus(IStatus.ERROR, "Unknown message format received while comparing using CVS diff command: {0}" + line); + return new CVSStatus(IStatus.ERROR, Policy.bind("CompareDiffListener.12", line)); //$NON-NLS-1$ } public IStatus errorLine( diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/listeners/DiffListener.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/listeners/DiffListener.java index a9d0765f5..073f4f8ad 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/listeners/DiffListener.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/listeners/DiffListener.java @@ -31,15 +31,13 @@ public class DiffListener extends CommandOutputListener { ICVSRepositoryLocation location, ICVSFolder commandRoot, IProgressMonitor monitor) { - // ignore any server messages - if (getServerMessage(line, location) == null) { - // Ensure that the line doesn't end with a CR. - // This can happen if the remote file has CR/LF in it. - if (line.length() > 0 && line.charAt(line.length() - 1) == '\r') { - line = line.substring(0, line.length() - 1); - } - patchStream.println(line); + + // Ensure that the line doesn't end with a CR. + // This can happen if the remote file has CR/LF in it. + if (line.length() > 0 && line.charAt(line.length() - 1) == '\r') { + line = line.substring(0, line.length() - 1); } + patchStream.println(line); return OK; } diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/connection/CVSRepositoryLocation.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/connection/CVSRepositoryLocation.java index 7a09747f5..7482480ce 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/connection/CVSRepositoryLocation.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/connection/CVSRepositoryLocation.java @@ -927,10 +927,10 @@ public class CVSRepositoryLocation extends PlatformObject implements ICVSReposit // remove the program name and the space message = message.substring(firstSpace + 1); // Quick fix to handle changes in server message format (see Bug 45138) - if (prefix.startsWith("[")) { + if (prefix.startsWith("[")) { //$NON-NLS-1$ // This is the server aborted message // Remove the pattern "[command_name aborted]: " - int closingBracket = message.indexOf("]: "); + int closingBracket = message.indexOf("]: "); //$NON-NLS-1$ if (closingBracket == -1) return null; // get what is inside the brackets String realPrefix = message.substring(1, closingBracket); @@ -938,7 +938,7 @@ public class CVSRepositoryLocation extends PlatformObject implements ICVSReposit int space = realPrefix.indexOf(' '); if (space == -1) return null; if (realPrefix.indexOf(' ', space +1) != -1) return null; - if (!realPrefix.substring(space +1).equals("aborted")) return null; + if (!realPrefix.substring(space +1).equals("aborted")) return null; //$NON-NLS-1$ // It's a match, return the rest of the line message = message.substring(closingBracket + 2); if (message.charAt(0) == ' ') { @@ -948,7 +948,7 @@ public class CVSRepositoryLocation extends PlatformObject implements ICVSReposit } else { // This is the server command message // Remove the pattern "command_name: " - int colon = message.indexOf(": "); + int colon = message.indexOf(": "); //$NON-NLS-1$ if (colon == -1) return null; // get what is before the colon String realPrefix = message.substring(0, colon); diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/messages.properties b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/messages.properties index 11f6f0109..227267940 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/messages.properties +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/messages.properties @@ -322,7 +322,6 @@ CVSProviderPlugin.20=CVS Workspace CVSProviderPlugin.21=Synchronizes the CVS managed resources in your workspace with their associated remote location CVSSyncTreeSubscriber.0={0} is not a valid comparison criteria for subscriber {1} CVSRevisionNumberCompareCriteria.1=Comparing revision numbers -RemoteTagSynchronizer.0=Refreshing {0} ReentrantLock.9=An error occurred writting CVS synchronization information to disk. Some information may be lost. CRLFDetectInputStream.0=CVS file {0} either contains invalid line endings on the server (CR/LF instead of just LF) or is a binary file that is not marked as -kb. SynchronizerSyncInfoCache.0=Synchronization information could not be cached for {0}. The only negative effect of this may be decreased performance. @@ -339,3 +338,10 @@ CVSSyncInfo.7=Invalid attempt to make file {0} in-sync. This operation can only CVSSyncInfo.8=Invalid attempt to make outgoing resource {0} in-sync. This operation only applies to incoming or conflicting changes. CVSSyncInfo.9=Cannot make {0} in-sync because its parent is not under CVS control. CVSSyncInfo.10=Cannot make {0} in-sync because there is no corresponding remote. +CVSCompareSubscriber.2=CVS Compare with {0} +CVSCompareSubscriber.3=Shows the differences between a tag and the workspace. +CompareDiffListener.11=Unsupported message sequence received while comparing using CVS diff command +CompareDiffListener.12=Unknown message format received while comparing using CVS diff command: {0} +AnnotateListener.3=Skipping binary file +AnnotateListener.4=Cannot annotate a binary file. +CVSWorkspaceSubscriber.1=Calculating synchronization state for {0} diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSLocalSyncElement.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSLocalSyncElement.java deleted file mode 100644 index e2334ca51..000000000 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSLocalSyncElement.java +++ /dev/null @@ -1,107 +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.resources; - - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.team.core.sync.ILocalSyncElement; -import org.eclipse.team.core.sync.IRemoteResource; -import org.eclipse.team.core.sync.LocalSyncElement; -import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.ICVSFolder; -import org.eclipse.team.internal.ccvs.core.ICVSResource; - -public class CVSLocalSyncElement extends LocalSyncElement { - - protected IRemoteResource base; - protected IResource local; - - public CVSLocalSyncElement(IResource local, IRemoteResource base) { - this.local = local; - this.base = base; - } - - /* - * @see RemoteSyncElement#create(IResource, IRemoteResource, IRemoteResource) - */ - public ILocalSyncElement create(IResource local, IRemoteResource base, Object data) { - return new CVSLocalSyncElement(local, base); - } - - /* - * @see ILocalSyncElement#getLocal() - */ - public IResource getLocal() { - return local; - } - - /* - * @see ILocalSyncElement#getBase() - */ - public IRemoteResource getBase() { - return base; - } - - /* - * @see ILocalSyncElement#isCheckedOut() - */ - public boolean isCheckedOut() { - return getLocal() != null; - } - - /* - * @see ILocalSyncElement#hasRemote() - */ - public boolean hasRemote() { - return getLocal() != null; - } - - /* - * @see RemoteSyncElement#getData() - */ - protected Object getData() { - return null; - } - - /* - * Answers the CVS resource for this sync element - */ - public ICVSResource getCVSResource() { - return getCVSResourceFor(getLocal()); - } - - /* - * @see LocalSyncElement#isIgnored(IResource) - */ - public boolean isIgnored(IResource child) { - ICVSResource cvsResource = getCVSResourceFor(getLocal()); - if(cvsResource==null || !cvsResource.isFolder() ) { - return false; - } else { - try { - ICVSResource managedChild = ((ICVSFolder)cvsResource).getChild(child.getName()); - return managedChild.isIgnored(); - } catch(CVSException e) { - return false; - } - } - } - - private ICVSResource getCVSResourceFor(IResource resource) { - if(resource.getType() != IResource.FILE) { - return new EclipseFolder((IContainer)resource); - } else { - return new EclipseFile((IFile)resource); - } - } -} diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSRemoteSyncElement.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSRemoteSyncElement.java deleted file mode 100644 index 6613ca6c3..000000000 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSRemoteSyncElement.java +++ /dev/null @@ -1,444 +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.resources; - - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.ILocalSyncElement; -import org.eclipse.team.core.sync.IRemoteResource; -import org.eclipse.team.core.sync.IRemoteSyncElement; -import org.eclipse.team.core.sync.RemoteSyncElement; -import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin; -import org.eclipse.team.internal.ccvs.core.ICVSFile; -import org.eclipse.team.internal.ccvs.core.ICVSFolder; -import org.eclipse.team.internal.ccvs.core.ICVSRemoteFile; -import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder; -import org.eclipse.team.internal.ccvs.core.ICVSResource; -import org.eclipse.team.internal.ccvs.core.ICVSResourceVisitor; -import org.eclipse.team.internal.ccvs.core.Policy; -import org.eclipse.team.internal.ccvs.core.client.Update; -import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo; -import org.eclipse.team.internal.ccvs.core.syncinfo.MutableResourceSyncInfo; -import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; -import org.eclipse.team.internal.ccvs.core.util.Assert; - -public class CVSRemoteSyncElement extends RemoteSyncElement { - - CVSLocalSyncElement localSync; - IRemoteResource remote; - boolean isThreeWay = true; - - public CVSRemoteSyncElement(boolean isThreeWay, IResource local, IRemoteResource base, IRemoteResource remote) { - localSync = new CVSLocalSyncElement(local, base); - this.remote = remote; - this.isThreeWay = isThreeWay; - } - - /* - * @see RemoteSyncElement#create(IResource, IRemoteResource, IRemoteResource) - */ - public IRemoteSyncElement create(boolean isThreeWay, IResource local, IRemoteResource base, IRemoteResource remote, Object data) { - return new CVSRemoteSyncElement(isThreeWay, local, base, remote); - } - - /* - * @see IRemoteSyncElement#getRemote() - */ - public IRemoteResource getRemote() { - return remote; - } - - /* - * @see LocalSyncElement#getData() - */ - protected Object getData() { - return localSync.getData(); - } - - /* - * @see ILocalSyncElement#getLocal() - */ - public IResource getLocal() { - return localSync.getLocal(); - } - - /* - * @see ILocalSyncElement#getBase() - */ - public IRemoteResource getBase() { - return localSync.getBase(); - } - - /* - * @see ILocalSyncElement#isCheckedOut() - */ - public boolean isCheckedOut() { - return localSync.isCheckedOut(); - } - - /* - * Local helper to indicate if the corresponding local resource has a base - */ - public boolean hasBase() { - return getBase() != null; - } - - /* - * @see ILocalSyncElement#hasRemote() - */ - public boolean hasRemote() { - return remote != null; - } - - /* - * @see LocalSyncElement#create(IResource, IRemoteResource, Object) - */ - public ILocalSyncElement create(IResource local, IRemoteResource base, Object data) { - return localSync.create(local, base, data); - } - /* - * @see LocalSyncElement#isIgnored(IResource) - */ - public boolean isIgnored(IResource resource) { - return localSync.isIgnored(resource); - } - /* - * @see IRemoteSyncElement#ignoreBaseTree() - */ - public boolean isThreeWay() { - return isThreeWay; - } - - /* - * Update the sync info of the local resource in such a way that the local changes can be committed. - */ - public void makeOutgoing(IProgressMonitor monitor) throws TeamException { - - int syncKind = getSyncKind(GRANULARITY_TIMESTAMP, monitor); - boolean incoming = (syncKind & DIRECTION_MASK) == INCOMING; - boolean outgoing = (syncKind & DIRECTION_MASK) == OUTGOING; - - ICVSResource local = localSync.getCVSResource(); - RemoteResource remote = (RemoteResource)getRemote(); - ResourceSyncInfo origInfo = local.getSyncInfo(); - MutableResourceSyncInfo info = null; - if(origInfo!=null) { - info = origInfo.cloneMutable(); - } - - if (outgoing) { - // The sync info is alright, it's already outgoing! - return; - } else if (incoming) { - // We have an incoming change, addition, or deletion that we want to ignore - if (local.exists()) { - // We could have an incoming change or deletion - if (remote == null) { - info.setAdded(); - } else { - // Otherwise change the revision to the remote revision and dirty the file - info.setRevision(remote.getSyncInfo().getRevision()); - info.setTimeStamp(null); - } - } else { - // We have an incoming add, turn it around as an outgoing delete - info = remote.getSyncInfo().cloneMutable(); - info.setDeleted(true); - } - } else if (local.exists()) { - // We have a conflict and a local resource! - if (hasRemote()) { - if (hasBase()) { - // We have a conflicting change, Update the local revision - info.setRevision(remote.getSyncInfo().getRevision()); - } else { - // We have conflictin additions. - // We need to fetch the contents of the remote to get all the relevant information (timestamp, permissions) - remote.getContents(Policy.monitorFor(monitor)); - info = remote.getSyncInfo().cloneMutable(); - } - } else if (hasBase()) { - // We have a remote deletion. Make the local an addition - info.setAdded(); - } else { - // There's a local, no base and no remote. We can't possible have a conflict! - Assert.isTrue(false); - } - } else { - // We have a conflict and there is no local! - if (hasRemote()) { - // We have a local deletion that conflicts with remote changes. - info.setRevision(remote.getSyncInfo().getRevision()); - info.setDeleted(true); - } else { - // We have conflicting deletions. Clear the sync info - info = null; - return; - } - } - if(info!=null) { - info.setTag(local.getParent().getFolderSyncInfo().getTag()); - } - ((ICVSFile)local).setSyncInfo(info, ICVSFile.UNKNOWN); - } - - /* - * Update the sync info of the local resource in such a way that the remote resource can be loaded - * ignore any local changes. - */ - public void makeIncoming(IProgressMonitor monitor) throws TeamException { - // To make outgoing deletions incoming, the local will not exist but - // it is still important to unmanage (e.g. delete all meta info) for the - // deletion. - CVSWorkspaceRoot.getCVSResourceFor(getLocal()).unmanage(null); - } - - /* - * Load the resource and folder sync info into the local from the remote - * - * This method can be used on incoming folder additions to set the folder sync info properly - * without hitting the server again. It also applies to conflicts that involves unmanaged - * local resources. - * - * If the local folder is already managed and is a cvs folder, this operation - * will throw an exception if the mapping does not match that of the remote. - */ - public void makeInSync(IProgressMonitor monitor) throws TeamException { - - // Only work on folders - if (! isContainer()) return; - - int syncKind = getSyncKind(GRANULARITY_TIMESTAMP, monitor); - boolean outgoing = (syncKind & DIRECTION_MASK) == OUTGOING; - if (outgoing) return; - - ICVSFolder local = (ICVSFolder)localSync.getCVSResource(); - RemoteFolder remote = (RemoteFolder)getRemote(); - - // The parent must be managed - if (! local.getParent().isCVSFolder()) - return; - - // If the folder already has CVS info, check that the remote and local match - if(local.isManaged() && local.isCVSFolder()) { - // Verify that the root and repository are the same - FolderSyncInfo remoteInfo = remote.getFolderSyncInfo(); - FolderSyncInfo localInfo = local.getFolderSyncInfo(); - if ( ! localInfo.getRoot().equals(remoteInfo.getRoot())) { - throw new CVSException(Policy.bind("CVSRemoteSyncElement.rootDiffers", new Object[] {local.getName(), remoteInfo.getRoot(), localInfo.getRoot()}));//$NON-NLS-1$ - } else if ( ! localInfo.getRepository().equals(remoteInfo.getRepository())) { - throw new CVSException(Policy.bind("CVSRemoteSyncElement.repositoryDiffers", new Object[] {local.getName(), remoteInfo.getRepository(), localInfo.getRepository()}));//$NON-NLS-1$ - } - // The folders are in sync so just return - return; - } - - // Ensure that the folder exists locally - if (! local.exists()) { - local.mkdir(); - } - - // Since the parent is managed, this will also set the resource sync info. It is - // impossible for an incoming folder addition to map to another location in the - // repo, so we assume that using the parent's folder sync as a basis is safe. - // It is also impossible for an incomming folder to be static. - FolderSyncInfo remoteInfo = remote.getFolderSyncInfo(); - FolderSyncInfo localInfo = local.getParent().getFolderSyncInfo(); - local.setFolderSyncInfo(new FolderSyncInfo(remoteInfo.getRepository(), remoteInfo.getRoot(), localInfo.getTag(), false)); - } - /* - * Make all the folders that have both a remote and local in sync by copying - * the sync information from the remote to the local - */ - public void makeFoldersInSync(IProgressMonitor progress) throws TeamException { - FolderSyncInfo remoteInfo = ((RemoteFolder)getRemote()).getFolderSyncInfo(); - ((ICVSFolder)localSync.getCVSResource()).setFolderSyncInfo(remoteInfo); - ILocalSyncElement[] children = members(progress); - for (int i = 0; i < children.length; i++) { - CVSRemoteSyncElement child = (CVSRemoteSyncElement)children[i]; - if (child.isContainer() && child.getLocal().exists() && child.getRemote() != null) { - child.makeFoldersInSync(progress); - } - } - } - /* - * @see ILocalSyncElement#getSyncKind(int, IProgressMonitor) - */ - public int getSyncKind(int granularity, IProgressMonitor progress) { - - // special handling for folders, the generic sync algorithm doesn't work well - // with CVS because folders are not in namespaces (e.g. they exist in all versions - // and branches). - if(isContainer() && isThreeWay()) { - int folderKind = IRemoteSyncElement.IN_SYNC; - IResource local = getLocal(); - ICVSRemoteFolder remote = (ICVSRemoteFolder)getRemote(); - ICVSFolder cvsFolder = (ICVSFolder)localSync.getCVSResource(); - boolean isCVSFolder = false; - try { - isCVSFolder = cvsFolder.isCVSFolder(); - } catch (CVSException e) { - // Assume the folder is not a CVS folder - } - if(!local.exists()) { - if(remote != null) { - if (isCVSFolder) { - if (containsOutgoingDeletions(cvsFolder)) { - // say the folder is in_sync even though it doesn't exist locally - folderKind = IRemoteSyncElement.IN_SYNC; - } else { - folderKind = IRemoteSyncElement.INCOMING | IRemoteSyncElement.ADDITION; - } - } else { - folderKind = IRemoteSyncElement.INCOMING | IRemoteSyncElement.ADDITION; - } - } else { - // ignore conflicting deletion to keep phantom sync info - } - } else { - if(remote == null) { - if(isCVSFolder) { - folderKind = IRemoteSyncElement.INCOMING | IRemoteSyncElement.DELETION; - } else { - folderKind = IRemoteSyncElement.OUTGOING | IRemoteSyncElement.ADDITION; - } - } else if(!isCVSFolder) { - folderKind = IRemoteSyncElement.CONFLICTING | IRemoteSyncElement.ADDITION; - } else { - // folder exists both locally and remotely and are considered in sync, however - // we aren't checking the folder mappings to ensure that they are the same. - } - } - return folderKind; - } - - // 1. Run the generic sync calculation algorithm, then handle CVS specific - // sync cases. - int kind = super.getSyncKind(granularity, progress); - - // 2. Set the CVS specific sync type based on the workspace sync state provided - // by the CVS server. - if(remote!=null && (kind & IRemoteSyncElement.PSEUDO_CONFLICT) == 0) { - int type = ((RemoteResource)remote).getWorkspaceSyncState(); - switch(type) { - // the server compared both text files and decided that it cannot merge - // them without line conflicts. - case Update.STATE_CONFLICT: - return kind | ILocalSyncElement.MANUAL_CONFLICT; - - // the server compared both text files and decided that it can safely merge - // them without line conflicts. - case Update.STATE_MERGEABLE_CONFLICT: - return kind | ILocalSyncElement.AUTOMERGE_CONFLICT; - } - } - - // 3. unmanage delete/delete conflicts and return that they are in sync - kind = handleDeletionConflicts(kind); - - return kind; - } - - /** - * Return true if the provided phantom folder conyains any outgoing file deletions. - * We only need to detect if there are any files since a phantom folder can only - * contain outgoing filre deletions and other folder. - * - * @param cvsFolder a phantom folder - * @return boolean - */ - private boolean containsOutgoingDeletions(ICVSFolder cvsFolder) { - final boolean result[] = new boolean[] { false }; - try { - cvsFolder.accept(new ICVSResourceVisitor() { - public void visitFile(ICVSFile file) throws CVSException { - // Do nothing. Files are handled below - } - public void visitFolder(ICVSFolder folder) throws CVSException { - if (folder.members(ICVSFolder.FILE_MEMBERS).length > 0) { - result[0] = true; - } else { - folder.acceptChildren(this); - } - } - }); - } catch (CVSException e) { - CVSProviderPlugin.log(e); - } - return result[0]; - } - - - /* - * If the resource has a delete/delete conflict then ensure that the local is unmanaged so that the - * sync info can be properly flushed. - */ - private int handleDeletionConflicts(int kind) { - if(kind == (IRemoteSyncElement.CONFLICTING | IRemoteSyncElement.DELETION | IRemoteSyncElement.PSEUDO_CONFLICT)) { - try { - ICVSResource cvsResource = localSync.getCVSResource(); - if(!isContainer() && cvsResource.isManaged()) { - cvsResource.unmanage(null); - } - return IRemoteSyncElement.IN_SYNC; - } catch(CVSException e) { - CVSProviderPlugin.log(e); - return IRemoteSyncElement.CONFLICTING | IRemoteSyncElement.DELETION; - } - } - return kind; - } - - /** - * @see RemoteSyncElement#timestampEquals(IRemoteResource, IRemoteResource) - */ - protected boolean timestampEquals(IRemoteResource e1, IRemoteResource e2) { - if(e1.isContainer()) { - if(e2.isContainer()) { - return true; - } - return false; - } - return e1.equals(e2); - } - - /** - * @see RemoteSyncElement#timestampEquals(IResource, IRemoteResource) - */ - protected boolean timestampEquals(IResource e1, IRemoteResource e2) { - if(e1.getType() != IResource.FILE) { - if(e2.isContainer()) { - return true; - } - return false; - } - ICVSFile cvsFile = CVSWorkspaceRoot.getCVSFileFor((IFile)e1); - try { - byte[] syncBytes1 = cvsFile.getSyncBytes(); - byte[] syncBytes2 = ((ICVSRemoteFile)e2).getSyncBytes(); - - if(syncBytes1 != null) { - if(ResourceSyncInfo.isDeletion(syncBytes1) || ResourceSyncInfo.isMerge(syncBytes1) || cvsFile.isModified(null)) { - return false; - } - return ResourceSyncInfo.getRevision(syncBytes1).equals(ResourceSyncInfo.getRevision(syncBytes2)); - } - return false; - } catch(CVSException e) { - CVSProviderPlugin.log(e); - return false; - } - } -} diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSWorkspaceRoot.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSWorkspaceRoot.java index 478b08c3c..a51961d79 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSWorkspaceRoot.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/CVSWorkspaceRoot.java @@ -11,43 +11,14 @@ package org.eclipse.team.internal.ccvs.core.resources; import java.io.File; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Path; +import org.eclipse.core.resources.*; +import org.eclipse.core.runtime.*; import org.eclipse.team.core.RepositoryProvider; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.IRemoteSyncElement; -import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin; -import org.eclipse.team.internal.ccvs.core.CVSStatus; -import org.eclipse.team.internal.ccvs.core.CVSTag; -import org.eclipse.team.internal.ccvs.core.CVSTeamProvider; -import org.eclipse.team.internal.ccvs.core.ICVSFile; -import org.eclipse.team.internal.ccvs.core.ICVSFolder; -import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder; -import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource; -import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation; -import org.eclipse.team.internal.ccvs.core.ICVSResource; -import org.eclipse.team.internal.ccvs.core.ICVSRunnable; -import org.eclipse.team.internal.ccvs.core.Policy; -import org.eclipse.team.internal.ccvs.core.client.Checkout; -import org.eclipse.team.internal.ccvs.core.client.Command; -import org.eclipse.team.internal.ccvs.core.client.Request; -import org.eclipse.team.internal.ccvs.core.client.Session; -import org.eclipse.team.internal.ccvs.core.client.Update; +import org.eclipse.team.internal.ccvs.core.*; +import org.eclipse.team.internal.ccvs.core.client.*; import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption; import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation; import org.eclipse.team.internal.ccvs.core.connection.CVSServerException; @@ -437,80 +408,11 @@ public class CVSWorkspaceRoot { } return remote; } - - public static IRemoteSyncElement getRemoteSyncTree(IResource resource, CVSTag tag, IProgressMonitor progress) throws TeamException { - ICVSResource managed = CVSWorkspaceRoot.getCVSResourceFor(resource); - ICVSRemoteResource remote = CVSWorkspaceRoot.getRemoteResourceFor(resource); - ICVSRemoteResource baseTree = null; - - // The resource doesn't have a remote base. - // However, we still need to check to see if its been created remotely by a third party. - if(resource.getType() == IResource.FILE) { - baseTree = remote; - ICVSRepositoryLocation location; - if (remote == null) { - // If there's no base for the file, get the repository location from the parent - ICVSRemoteResource parent = CVSWorkspaceRoot.getRemoteResourceFor(resource.getParent()); - if (parent == null) { - throw new CVSException(new CVSStatus(CVSStatus.ERROR, Policy.bind("CVSTeamProvider.unmanagedParent", resource.getFullPath().toString()), null)); //$NON-NLS-1$ - } - location = parent.getRepository(); - } else { - location = remote.getRepository(); - } - remote = RemoteFolderTreeBuilder.buildRemoteTree((CVSRepositoryLocation)location, (ICVSFile)managed, tag, progress); - } else { - if (remote == null) { - remote = getRemoteTreeFromParent(resource, managed, tag, progress); - } else { - ICVSRepositoryLocation location = remote.getRepository(); - baseTree = RemoteFolderTreeBuilder.buildBaseTree((CVSRepositoryLocation)location, (ICVSFolder)managed, tag, progress); - remote = RemoteFolderTreeBuilder.buildRemoteTree((CVSRepositoryLocation)location, (ICVSFolder)managed, tag, progress); - } - } - return new CVSRemoteSyncElement(true /*three way*/, resource, baseTree, remote); - } - - /** - * Sync the given unshared project with the given repository and module. - */ - public static IRemoteSyncElement getRemoteSyncTree(IProject project, ICVSRepositoryLocation location, String moduleName, CVSTag tag, IProgressMonitor progress) throws TeamException { - if (CVSWorkspaceRoot.getCVSFolderFor(project).isCVSFolder()) { - return getRemoteSyncTree(project, tag, progress); - } else { - progress.beginTask(null, 100); - RemoteFolder folder = new RemoteFolder(null, location, moduleName, tag); - RemoteFolderTree remote = RemoteFolderTreeBuilder.buildRemoteTree((CVSRepositoryLocation)folder.getRepository(), folder, folder.getTag(), Policy.subMonitorFor(progress, 80)); - CVSRemoteSyncElement tree = new CVSRemoteSyncElement(true /*three way*/, project, null, remote); - tree.makeFoldersInSync(Policy.subMonitorFor(progress, 10)); - RepositoryProvider.map(project, CVSProviderPlugin.getTypeId()); - - progress.done(); - return tree; - } - } - - public static IRemoteSyncElement getRemoteSyncTree(IProject project, IResource[] resources, CVSTag tag, IProgressMonitor progress) throws TeamException { - ICVSResource managed = CVSWorkspaceRoot.getCVSResourceFor(project); - ICVSRemoteResource remote = CVSWorkspaceRoot.getRemoteResourceFor(project); - if (remote == null) { - return new CVSRemoteSyncElement(true /*three way*/, project, null, null); - } - ArrayList cvsResources = new ArrayList(); - for (int i = 0; i < resources.length; i++) { - cvsResources.add(CVSWorkspaceRoot.getCVSResourceFor(resources[i])); - } - CVSRepositoryLocation location = (CVSRepositoryLocation)remote.getRepository(); - ICVSRemoteResource base = RemoteFolderTreeBuilder.buildBaseTree(location, (ICVSFolder)managed, tag, progress); - remote = RemoteFolderTreeBuilder.buildRemoteTree(location, (ICVSFolder)managed, (ICVSResource[]) cvsResources.toArray(new ICVSResource[cvsResources.size()]), tag, progress); - return new CVSRemoteSyncElement(true /*three way*/, project, base, remote); - } - public static ICVSRemoteResource getRemoteTree(IResource resource, CVSTag tag, IProgressMonitor progress) throws TeamException { return getRemoteTree(resource, tag, false /* cache file contents hint */, progress); } - + /** * Return the remote tree that corresponds to the given local resource. Return * null if the remote tree doesn't exist remotely or if the local @@ -531,9 +433,8 @@ public class CVSWorkspaceRoot { remote = getRemoteTreeFromParent(resource, managed, tag, Policy.subMonitorFor(progress, 50)); if (cacheFileContentsHint && remote != null && remote instanceof RemoteFile) { RemoteFile file = (RemoteFile)remote; - if (!file.isContentsCached()) { - file.fetchContents(Policy.subMonitorFor(progress, 50)); - } + // get the storage for the file to ensure that the contents are cached + file.getStorage(Policy.subMonitorFor(progress, 50)); } progress.done(); } else if(resource.getType() == IResource.FILE) { diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java index 91a7581b2..92b67693c 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java @@ -801,20 +801,27 @@ public class EclipseSynchronizer implements IFlushOperation { } else { infos = SyncFileWriter.readAllResourceSync(container); } - if (infos != null) { - for (int i = 0; i < infos.length; i++) { - byte[] syncBytes = infos[i]; - IPath name = new Path(getName(syncBytes)); - IResource resource; - if (isFolder(syncBytes)) { - resource = container.getFolder(name); - } else { - resource = container.getFile(name); + try { + if (infos != null) { + for (int i = 0; i < infos.length; i++) { + byte[] syncBytes = infos[i]; + IPath name = new Path(getName(syncBytes)); + IResource resource; + if (isFolder(syncBytes)) { + resource = container.getFolder(name); + } else { + resource = container.getFile(name); + } + getSyncInfoCacheFor(resource).setCachedSyncBytes(resource, syncBytes, canModifyWorkspace); } - getSyncInfoCacheFor(resource).setCachedSyncBytes(resource, syncBytes, canModifyWorkspace); } + getSyncInfoCacheFor(container).setResourceSyncInfoCached(container); + } catch (CVSException e) { + if (Policy.DEBUG_METAFILE_CHANGES) { + System.err.println("Failed to cache Entries for folder " + container.getFullPath()); //$NON-NLS-1$ + } + throw e; } - getSyncInfoCacheFor(container).setResourceSyncInfoCached(container); } } diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileContentCachingService.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileContentCachingService.java index e7b9146e4..f412764ac 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileContentCachingService.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileContentCachingService.java @@ -15,6 +15,7 @@ import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.team.core.TeamException; import org.eclipse.team.internal.ccvs.core.CVSException; import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin; import org.eclipse.team.internal.ccvs.core.CVSTag; @@ -67,10 +68,13 @@ public class FileContentCachingService { try { RemoteFolderTreeBuilder builder = new RemoteFolderTreeBuilder(repository, file.getParent(), tag); RemoteFile remote = builder.buildTree(file, monitor); - if (builder.getFileDiffs().length > 0 && !remote.isContentsCached()) { - remote.fetchContents(Policy.subMonitorFor(monitor, 50)); + if (builder.getFileDiffs().length > 0) { + // Getting the storage of the file will cache the contents + remote.getStorage(Policy.subMonitorFor(monitor, 50)); } return remote; + } catch (TeamException e) { + throw CVSException.wrapException(e); } finally { monitor.done(); } diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java index 3b25d5e1a..5069467e7 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java @@ -63,7 +63,7 @@ public class FileModificationManager implements IResourceChangeListener, ISavePa public void resourceChanged(IResourceChangeEvent event) { try { event.getDelta().accept(new IResourceDeltaVisitor() { - public boolean visit(IResourceDelta delta) throws CoreException { + public boolean visit(IResourceDelta delta) { IResource resource = delta.getResource(); if (resource.getType()==IResource.PROJECT) { @@ -162,10 +162,8 @@ public class FileModificationManager implements IResourceChangeListener, ISavePa IFile file = (IFile)mFile.getIResource(); file.setSessionProperty(UPDATE_TIMESTAMP, new Long(file.getModificationStamp())); } - } catch (CVSException e) { - CVSProviderPlugin.log(e); } catch (CoreException e) { - CVSProviderPlugin.log(CVSException.wrapException(e)); + CVSProviderPlugin.log(e); } } @@ -173,7 +171,7 @@ public class FileModificationManager implements IResourceChangeListener, ISavePa * Handle added and changed resources by signaling the change to the corresponding * CVS resource and recording the change for broadcast to interested listeners. */ - /* private */void resourceChanged(IResource resource, boolean addition) throws CoreException { + /* private */void resourceChanged(IResource resource, boolean addition) { if (isCleanUpdate(resource)) return; try { EclipseResource cvsResource = (EclipseResource)CVSWorkspaceRoot.getCVSResourceFor(resource); @@ -182,7 +180,8 @@ public class FileModificationManager implements IResourceChangeListener, ISavePa modifiedResources.add(resource); } } catch (CVSException e) { - throw e.toCoreException(); + // Log the exception and continue + CVSProviderPlugin.log(e); } } diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java index 237191eea..b6efc810b 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java @@ -12,49 +12,17 @@ package org.eclipse.team.internal.ccvs.core.resources; import java.io.ByteArrayInputStream; import java.io.InputStream; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; +import java.util.*; -import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IStorage; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.*; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.IRemoteResource; -import org.eclipse.team.core.sync.RemoteContentsCache; -import org.eclipse.team.core.sync.RemoteContentsCacheEntry; -import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin; -import org.eclipse.team.internal.ccvs.core.CVSStatus; -import org.eclipse.team.internal.ccvs.core.CVSTag; -import org.eclipse.team.internal.ccvs.core.ICVSFile; -import org.eclipse.team.internal.ccvs.core.ICVSFolder; -import org.eclipse.team.internal.ccvs.core.ICVSRemoteFile; -import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder; -import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource; -import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation; -import org.eclipse.team.internal.ccvs.core.ICVSResource; -import org.eclipse.team.internal.ccvs.core.ICVSResourceVisitor; -import org.eclipse.team.internal.ccvs.core.ILogEntry; -import org.eclipse.team.internal.ccvs.core.Policy; -import org.eclipse.team.internal.ccvs.core.client.Command; -import org.eclipse.team.internal.ccvs.core.client.Log; -import org.eclipse.team.internal.ccvs.core.client.Session; -import org.eclipse.team.internal.ccvs.core.client.Update; -import org.eclipse.team.internal.ccvs.core.client.Command.KSubstOption; -import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption; -import org.eclipse.team.internal.ccvs.core.client.Command.QuietOption; +import org.eclipse.team.internal.ccvs.core.*; +import org.eclipse.team.internal.ccvs.core.client.*; +import org.eclipse.team.internal.ccvs.core.client.Command.*; import org.eclipse.team.internal.ccvs.core.client.listeners.LogListener; import org.eclipse.team.internal.ccvs.core.connection.CVSServerException; -import org.eclipse.team.internal.ccvs.core.syncinfo.MutableResourceSyncInfo; -import org.eclipse.team.internal.ccvs.core.syncinfo.NotifyInfo; -import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; +import org.eclipse.team.internal.ccvs.core.syncinfo.*; import org.eclipse.team.internal.ccvs.core.util.Assert; /** @@ -93,6 +61,9 @@ public class RemoteFile extends RemoteResource implements ICVSRemoteFile { return file; } + /** + * This method is used by the CVS subscribers to create file handles. + */ public static RemoteFile fromBytes(IResource local, byte[] bytes, byte[] parentBytes) throws CVSException { Assert.isNotNull(bytes); Assert.isTrue(local.getType() == IResource.FILE); @@ -102,13 +73,6 @@ public class RemoteFile extends RemoteResource implements ICVSRemoteFile { return file; } - public static RemoteFile getRemote(IFile local, byte[] bytes) throws CVSException { - RemoteFolder parent = (RemoteFolder)CVSWorkspaceRoot.getRemoteResourceFor(local.getParent()); - RemoteFile file = new RemoteFile(parent, bytes); - parent.setChildren(new ICVSRemoteResource[] {file}); - return file; - } - /** * Constructor for RemoteFile that should be used when nothing is know about the * file ahead of time. @@ -168,30 +132,28 @@ public class RemoteFile extends RemoteResource implements ICVSRemoteFile { * @see ICVSRemoteFile#getContents() */ public InputStream getContents(IProgressMonitor monitor) throws CVSException { - // Ensure that the contents are cached from the server - if (!isContentsCached()) { - fetchContents(monitor); - } - // If the fetch succeeded but no contents were cached from the server - // than we can assume that the remote file has no contents. - if (!isContentsCached()) { - setContents(new ByteArrayInputStream(new byte[0]), UPDATED, false /* keep history */, monitor); + try { + return getStorage(monitor).getContents(); + } catch (CoreException e) { + throw CVSException.wrapException(e); } - // Return the cached contents - InputStream cached = getCachedContents(); - Assert.isNotNull(cached, "Caching error for file " + getRepositoryRelativePath()); //$NON-NLS-1$ - return cached; } - /* package*/ void fetchContents(IProgressMonitor monitor) throws CVSException { + protected void fetchContents(IProgressMonitor monitor) throws TeamException { try { aboutToReceiveContents(getSyncBytes()); internalFetchContents(monitor); + // If the fetch succeeded but no contents were cached from the server + // than we can assume that the remote file has no contents. + if (!isContentsCached()) { + setContents(new ByteArrayInputStream(new byte[0]), monitor); + } } finally { doneReceivingContents(); } } - /* package*/ void internalFetchContents(IProgressMonitor monitor) throws CVSException { + + private void internalFetchContents(IProgressMonitor monitor) throws CVSException { monitor.beginTask(Policy.bind("RemoteFile.getContents"), 100);//$NON-NLS-1$ if (getRevision().equals(ResourceSyncInfo.ADDED_REVISION)) { // The revision of the remote file is not known so we need to use the tag to get the status of the file @@ -322,18 +284,6 @@ public class RemoteFile extends RemoteResource implements ICVSRemoteFile { return file; } - /** - * @see ICVSFile#getSize() - */ - public long getSize() { - if (fetching) return 0; - RemoteContentsCacheEntry entry = getCacheEntry(); - if (entry == null) { - return 0; - } - return entry.getSize(); - } - /** * @see ICVSFile#getSyncInfo() */ @@ -388,9 +338,13 @@ public class RemoteFile extends RemoteResource implements ICVSRemoteFile { if (!fetching) { // Return the cached contents if (isContentsCached()) { - InputStream cached = getCachedContents(); - if (cached != null) { - return cached; + try { + InputStream cached = getCachedContents(); + if (cached != null) { + return cached; + } + } catch (TeamException e) { + throw CVSException.wrapException(e); } } } @@ -400,57 +354,27 @@ public class RemoteFile extends RemoteResource implements ICVSRemoteFile { return new ByteArrayInputStream(new byte[0]); } - private InputStream getCachedContents() throws CVSException { - try { - RemoteContentsCacheEntry entry = getCacheEntry(); - byte[] newSyncBytes = entry.getSyncBytes(); - if (newSyncBytes != null) { - // Make sure the sync bytes match the content that is being accessed - syncBytes = newSyncBytes; + protected InputStream getCachedContents() throws TeamException { + if (isHandleCached()) { + RemoteFile file = (RemoteFile)getCachedHandle(); + if (file != null) { + byte[] newSyncBytes = file.getSyncBytes(); + if (newSyncBytes != null) { + // Make sure the sync bytes match the content that is being accessed + syncBytes = newSyncBytes; + } } - return entry.getContents(); - } catch (TeamException e) { - throw CVSException.wrapException(e); } + return super.getCachedContents(); } public void setContents(InputStream stream, int responseType, boolean keepLocalHistory, IProgressMonitor monitor) throws CVSException { try { - getCacheEntry().setContents(stream, monitor); + setContents(stream, monitor); } catch (TeamException e) { throw CVSException.wrapException(e); } } - - private RemoteContentsCache getRemoteContentsCache() { - return CVSProviderPlugin.getPlugin().getRemoteContentsCache(); - } - - /* - * Return the cache relative path for the receiver as - * host/cvs/root/module/path/.#filename revision - */ - private String getCacheRelativePath() { - ICVSRepositoryLocation location = getRepository(); - IPath path = new Path(location.getHost()); - path = path.append(location.getRootDirectory()); - path = path.append(parent.getRepositoryRelativePath()); - path = path.append(getName() + ' ' + getRevision()); - return path.toString(); - } - - /* - * Return whether there are already contents cached for the given handle - */ - public boolean isContentsCached() { - if (getRevision().equals(ResourceSyncInfo.ADDED_REVISION)) return false; - String cacheRelativePath = getCacheRelativePath(); - if (!getRemoteContentsCache().hasEntry(cacheRelativePath)) { - return false; - } - RemoteContentsCacheEntry entry = getRemoteContentsCache().getCacheEntry(cacheRelativePath); - return entry.getState() == RemoteContentsCacheEntry.READY; - } /* * @see ICVSFile#setReadOnly(boolean) @@ -490,8 +414,8 @@ public class RemoteFile extends RemoteResource implements ICVSRemoteFile { /* * @see IRemoteResource#members(IProgressMonitor) */ - public IRemoteResource[] members(IProgressMonitor progress) { - return new IRemoteResource[0]; + public ICVSRemoteResource[] members(IProgressMonitor progress) { + return new ICVSRemoteResource[0]; } /* @@ -610,16 +534,16 @@ public class RemoteFile extends RemoteResource implements ICVSRemoteFile { */ public void setSyncBytes(byte[] syncBytes, int modificationState) { if (fetching) { - RemoteContentsCacheEntry entry = getCacheEntry(); - entry.setSyncBytes(syncBytes); + RemoteFile file = (RemoteFile)getCachedHandle(); + if (file == null) { + cacheHandle(); + } else if (file != this) { + file.setSyncBytes(syncBytes, modificationState); + } } this.syncBytes = syncBytes; } - private RemoteContentsCacheEntry getCacheEntry() { - return getRemoteContentsCache().getCacheEntry(getCacheRelativePath()); - } - public String toString() { return super.toString() + " " + getRevision(); //$NON-NLS-1$ } @@ -647,31 +571,6 @@ public class RemoteFile extends RemoteResource implements ICVSRemoteFile { return entry.getAuthor(); } - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.IRemoteResource#getBufferedStorage(org.eclipse.core.runtime.IProgressMonitor) - */ - public IStorage getBufferedStorage(IProgressMonitor monitor) throws TeamException { - // Invoke getContents which ensures that contents are cached - getContents(monitor); - return new IStorage() { - public InputStream getContents() throws CoreException { - return RemoteFile.this.getContents(); - } - public IPath getFullPath() { - return new Path(getRepositoryRelativePath()); - } - public String getName() { - return RemoteFile.this.getName(); - } - public boolean isReadOnly() { - return true; - } - public Object getAdapter(Class adapter) { - return RemoteFile.this.getAdapter(adapter); - } - }; - } - /** * Callback which indicates that the remote file is about to receive contents that should be cached * @param entryLine @@ -687,4 +586,13 @@ public class RemoteFile extends RemoteResource implements ICVSRemoteFile { public void doneReceivingContents() { fetching = false; } + + /* (non-Javadoc) + * @see org.eclipse.team.core.synchronize.ResourceVariant#isContentsCached() + */ + public boolean isContentsCached() { + // Made public for use by FileContentCachingService + return super.isContentsCached(); + } + } diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolder.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolder.java index 59c08034f..2132a6c91 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolder.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolder.java @@ -16,29 +16,10 @@ import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IStorage; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.*; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.IRemoteResource; -import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin; -import org.eclipse.team.internal.ccvs.core.CVSStatus; -import org.eclipse.team.internal.ccvs.core.CVSTag; -import org.eclipse.team.internal.ccvs.core.ICVSFile; -import org.eclipse.team.internal.ccvs.core.ICVSFolder; -import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder; -import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource; -import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation; -import org.eclipse.team.internal.ccvs.core.ICVSResource; -import org.eclipse.team.internal.ccvs.core.ICVSResourceVisitor; -import org.eclipse.team.internal.ccvs.core.ICVSRunnable; -import org.eclipse.team.internal.ccvs.core.Policy; -import org.eclipse.team.internal.ccvs.core.client.Command; -import org.eclipse.team.internal.ccvs.core.client.Session; -import org.eclipse.team.internal.ccvs.core.client.Update; +import org.eclipse.team.internal.ccvs.core.*; +import org.eclipse.team.internal.ccvs.core.client.*; import org.eclipse.team.internal.ccvs.core.client.Command.GlobalOption; import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption; import org.eclipse.team.internal.ccvs.core.client.listeners.IUpdateMessageListener; @@ -429,7 +410,7 @@ public class RemoteFolder extends RemoteResource implements ICVSRemoteFolder, IC /* * @see IRemoteResource#members(IProgressMonitor) */ - public IRemoteResource[] members(IProgressMonitor progress) throws TeamException { + public ICVSRemoteResource[] members(IProgressMonitor progress) throws TeamException { return getMembers(progress); } @@ -605,8 +586,8 @@ public class RemoteFolder extends RemoteResource implements ICVSRemoteFolder, IC /* (non-Javadoc) * @see org.eclipse.team.core.sync.IRemoteResource#getContentIdentifier() */ - public String getContentIdentifier() throws TeamException { - return null; + public String getContentIdentifier() { + return getTag().getName(); } /* (non-Javadoc) @@ -615,13 +596,6 @@ public class RemoteFolder extends RemoteResource implements ICVSRemoteFolder, IC public String getCreatorDisplayName() throws TeamException { return null; } - - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.IRemoteResource#getBufferedStorage(org.eclipse.core.runtime.IProgressMonitor) - */ - public IStorage getBufferedStorage(IProgressMonitor monitor) throws TeamException { - return null; - } /* (non-Javadoc) * @see org.eclipse.team.internal.ccvs.core.ICVSResource#isManaged() @@ -630,4 +604,11 @@ public class RemoteFolder extends RemoteResource implements ICVSRemoteFolder, IC return super.isManaged() && isCVSFolder(); } + /* (non-Javadoc) + * @see org.eclipse.team.core.synchronize.ResourceVariant#fetchContents(org.eclipse.core.runtime.IProgressMonitor) + */ + protected void fetchContents(IProgressMonitor monitor) throws TeamException { + // This should not get called for folders + } + } diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteResource.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteResource.java index 1c36389b9..52bc6999c 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteResource.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteResource.java @@ -12,15 +12,10 @@ package org.eclipse.team.internal.ccvs.core.resources; import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.core.runtime.*; import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.CVSTag; -import org.eclipse.team.internal.ccvs.core.ICVSFolder; -import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder; -import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource; -import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation; +import org.eclipse.team.core.synchronize.CachedResourceVariant; +import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.core.client.Update; import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; import org.eclipse.team.internal.ccvs.core.util.Assert; @@ -32,7 +27,7 @@ import org.eclipse.team.internal.ccvs.core.util.Util; * resources that reside in a CVS repository but have not necessarily been loaded * locally. */ -public abstract class RemoteResource extends PlatformObject implements ICVSRemoteResource { +public abstract class RemoteResource extends CachedResourceVariant implements ICVSRemoteResource { protected RemoteFolder parent; protected String name; @@ -212,4 +207,23 @@ public abstract class RemoteResource extends PlatformObject implements ICVSRemot public String toString() { return "Remote " + (isContainer() ? "Folder: " : "File: ") + getName(); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ } + + /* (non-Javadoc) + * @see org.eclipse.team.core.synchronize.ResourceVariant#getUniquePath() + */ + public String getCachePath() { + ICVSRepositoryLocation location = getRepository(); + IPath path = new Path(location.getHost()); + path = path.append(location.getRootDirectory()); + path = path.append(parent.getRepositoryRelativePath()); + path = path.append(getName() + ' ' + getContentIdentifier()); + return path.toString(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.synchronize.ResourceVariant#getCacheId() + */ + protected String getCacheId() { + return CVSProviderPlugin.ID; + } } diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SessionPropertySyncInfoCache.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SessionPropertySyncInfoCache.java index 96672c101..403845eb3 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SessionPropertySyncInfoCache.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SessionPropertySyncInfoCache.java @@ -10,29 +10,12 @@ *******************************************************************************/ package org.eclipse.team.internal.ccvs.core.resources; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; +import java.util.*; -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.IResourceStatus; -import org.eclipse.core.resources.IResourceVisitor; -import org.eclipse.core.resources.ISaveContext; -import org.eclipse.core.resources.ISaveParticipant; -import org.eclipse.core.resources.ISynchronizer; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.QualifiedName; +import org.eclipse.core.resources.*; +import org.eclipse.core.runtime.*; import org.eclipse.team.core.RepositoryProvider; -import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin; -import org.eclipse.team.internal.ccvs.core.ICVSDecoratorEnablementListener; -import org.eclipse.team.internal.ccvs.core.Policy; +import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo; import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; import org.eclipse.team.internal.ccvs.core.util.FileNameMatcher; @@ -44,8 +27,7 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; * state for all cvs managed folders are persisted using the resource's plugin * synchronizer. */ -/*package*/ class SessionPropertySyncInfoCache extends SyncInfoCache - implements ISaveParticipant, ICVSDecoratorEnablementListener { +/*package*/ class SessionPropertySyncInfoCache extends SyncInfoCache implements ISaveParticipant { // key used on a folder to indicate that the resource sync has been cahced for it's children private static final QualifiedName RESOURCE_SYNC_CACHED_KEY = new QualifiedName(CVSProviderPlugin.ID, "resource-sync-cached"); //$NON-NLS-1$ @@ -55,7 +37,6 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; private static final FolderSyncInfo NULL_FOLDER_SYNC_INFO = new FolderSyncInfo("", "", null, false); //$NON-NLS-1$ //$NON-NLS-2$ private QualifiedName FOLDER_DIRTY_STATE_KEY = new QualifiedName(CVSProviderPlugin.ID, "folder-dirty-state-cached"); //$NON-NLS-1$ - private boolean isDecoratorEnabled = true; private boolean hasBeenSaved = false; // defer to the sychronizer if there is no sync info @@ -67,9 +48,7 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; try { // this save participant is removed when the plugin is shutdown. ResourcesPlugin.getWorkspace().addSaveParticipant(CVSProviderPlugin.getPlugin(), this); - CVSProviderPlugin.getPlugin().addDecoratorEnablementListener(this); - - final ISynchronizer synchronizer = ResourcesPlugin.getWorkspace().getSynchronizer(); + ISynchronizer synchronizer = ResourcesPlugin.getWorkspace().getSynchronizer(); synchronizer.add(FOLDER_DIRTY_STATE_KEY); } catch (CoreException e) { CVSProviderPlugin.log(e); @@ -422,7 +401,7 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; boolean fullSave = (context.getKind() == ISaveContext.FULL_SAVE); boolean projectSave = (context.getKind() == ISaveContext.PROJECT_SAVE); - if(isDecoratorEnabled && (projectSave || fullSave)) { + if((projectSave || fullSave)) { // persist all session properties for folders into sync info. final ISynchronizer synchronizer = ResourcesPlugin.getWorkspace().getSynchronizer(); @@ -466,40 +445,6 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; hasBeenSaved = true; } } - - /* (non-Javadoc) - * @see ICVSDecoratorEnablementListener#decoratorEnablementChanged(boolean) - */ - public void decoratorEnablementChanged(boolean enabled) { - isDecoratorEnabled = enabled; - if(!enabled && !hasBeenSaved) { - // flush the dirty state cache for all managed resources - IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); - for (int i = 0; i < projects.length; i++) { - IProject project = projects[i]; - RepositoryProvider provider = RepositoryProvider.getProvider( - project, - CVSProviderPlugin.getTypeId()); - - if (provider != null) { - try { - project.accept(new IResourceVisitor() { - public boolean visit(IResource resource) throws CoreException { - try { - flushDirtyCache(resource); - } catch(CVSException e) { - throw new CoreException(e.getStatus()); - } - return true; - } - }); - } catch (CoreException e) { - CVSProviderPlugin.log(e); - } - } - } - } - } /* * Called to clear the folder dirty state from the resource sync tree and stop persisting diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/BaseSynchronizer.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/BaseSynchronizer.java deleted file mode 100644 index 2863e4673..000000000 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/BaseSynchronizer.java +++ /dev/null @@ -1,94 +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.IContainer; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.QualifiedName; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.RemoteSynchronizer; -import org.eclipse.team.core.sync.IRemoteResource; -import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin; -import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; -import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer; - -/** - * A base sychronizer provides access to the base sync bytes for the - * resources in the local workspace - */ -public class BaseSynchronizer extends RemoteSynchronizer { - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSynchronizer#getSyncBytes(org.eclipse.core.resources.IResource) - */ - public byte[] getSyncBytes(IResource resource) throws CVSException { - if (resource.getType() == IResource.FILE) { - // For a file, return the entry line - byte[] bytes = EclipseSynchronizer.getInstance().getSyncBytes(resource); - if (bytes != null) { - // Use the base sync info (i.e. no deletion or addition) - if (ResourceSyncInfo.isDeletion(bytes)) { - bytes = ResourceSyncInfo.convertFromDeletion(bytes); - } else if (ResourceSyncInfo.isAddition(bytes)) { - bytes = null; - } - } - return bytes; - } else { - // For a folder, return the folder sync info bytes - FolderSyncInfo info = EclipseSynchronizer.getInstance().getFolderSync((IContainer)resource); - if (info == null) return null; - return info.getBytes(); - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSynchronizer#getSyncName() - */ - protected QualifiedName getSyncName() { - return new QualifiedName(CVSProviderPlugin.ID, "workspace"); //$NON-NLS-1$ - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSynchronizer#refresh(org.eclipse.core.resources.IResource[], int, boolean, org.eclipse.core.runtime.IProgressMonitor) - */ - public IResource[] refresh( - IResource resource, - int depth, - boolean cacheFileContentsHint, - IProgressMonitor monitor) - throws TeamException { - - // TODO Ensure that file contents are cached for modified local files - try { - monitor.beginTask(null, 100); - return new IResource[0]; - } finally { - monitor.done(); - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSynchronizer#getRemoteResource(org.eclipse.core.resources.IResource) - */ - public IRemoteResource getRemoteResource(IResource resource) throws TeamException { - return CVSWorkspaceRoot.getRemoteResourceFor(resource); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.RemoteSynchronizer#hasRemote(org.eclipse.core.resources.IResource) - */ - public boolean hasRemote(IResource resource) throws TeamException { - return getSyncBytes(resource) != null; - } -} 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 new file mode 100644 index 000000000..e3059df18 --- /dev/null +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSBaseSynchronizationCache.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * 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.IResource; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree; +import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer; + + +public class CVSBaseSynchronizationCache extends ResourceVariantTree { + public void dispose() { + // Do nothing + } + public byte[] getBytes(IResource resource) throws TeamException { + if (resource.getType() == IResource.FILE) { + // For a file, return the entry line + byte[] bytes = EclipseSynchronizer.getInstance().getSyncBytes(resource); + if (bytes != null) { + // Use the base sync info (i.e. no deletion or addition) + if (ResourceSyncInfo.isDeletion(bytes)) { + bytes = ResourceSyncInfo.convertFromDeletion(bytes); + } else if (ResourceSyncInfo.isAddition(bytes)) { + bytes = null; + } + } + return bytes; + } else { + // For a folder, return the folder sync info bytes + FolderSyncInfo info = EclipseSynchronizer.getInstance().getFolderSync((IContainer)resource); + if (info == null) return null; + return info.getBytes(); + } + } + public boolean isVariantKnown(IResource resource) throws TeamException { + return getBytes(resource) != null; + } + public boolean removeBytes(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 { + throw new UnsupportedOperationException(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.utils.SynchronizationCache#members(org.eclipse.core.resources.IResource) + */ + public IResource[] members(IResource resource) throws TeamException { + if(resource.getType() == IResource.FILE) { + return new IResource[0]; + } + return EclipseSynchronizer.getInstance().members((IContainer)resource); + } +} \ No newline at end of file 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 new file mode 100644 index 000000000..a3c413710 --- /dev/null +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSDescendantSynchronizationCache.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * 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.team.core.TeamException; +import org.eclipse.team.internal.core.subscribers.caches.*; +import org.eclipse.team.internal.ccvs.core.*; + +/** + * CVS sycnrhonization cache that ignores stale remote bytes + */ +public class CVSDescendantSynchronizationCache extends DescendantResourceVariantTree { + + public CVSDescendantSynchronizationCache(ResourceVariantTree baseCache, PersistantResourceVariantTree remoteCache) { + super(baseCache, remoteCache); + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.DescendantSynchronizationCache#isDescendant(org.eclipse.core.resources.IResource, byte[], byte[]) + */ + protected boolean isDescendant(IResource resource, byte[] baseBytes, byte[] remoteBytes) throws TeamException { + if (resource.getType() != IResource.FILE) return true; + try { + return ResourceSyncInfo.isLaterRevisionOnSameBranch(remoteBytes, baseBytes); + } catch (CVSException e) { + throw TeamException.asTeamException(e); + } + } + + /* (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", ((PersistantResourceVariantTree)getRemoteTree()).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/CVSRefreshOperation.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSRefreshOperation.java new file mode 100644 index 000000000..395166a28 --- /dev/null +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSRefreshOperation.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * 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.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; +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.ResourceVariantTree; +import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTreeRefresh; + +/** + * CVS Specific refresh operation + */ +public class CVSRefreshOperation extends ResourceVariantTreeRefresh { + + private ResourceVariantTree cache, baseCache; + private CVSTag tag; + private boolean cacheFileContentsHint; + + public CVSRefreshOperation(ResourceVariantTree cache, ResourceVariantTree 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 ResourceVariantTree getResourceVariantTree() { + 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#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 { + // 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); + } + +} diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSRemoteSynchronizer.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSRemoteSynchronizer.java deleted file mode 100644 index 36396bbdf..000000000 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSRemoteSynchronizer.java +++ /dev/null @@ -1,93 +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.core.subscribers.RemoteBytesSynchronizer; -import org.eclipse.team.core.sync.IRemoteResource; -import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin; -import org.eclipse.team.internal.ccvs.core.Policy; -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; - -/** - * CVS specific remote synchronizer behavior - */ -public abstract class CVSRemoteSynchronizer extends RemoteBytesSynchronizer { - - public static final String SYNC_KEY_QUALIFIER = "org.eclipse.team.cvs"; //$NON-NLS-1$ - - public CVSRemoteSynchronizer(String id) { - super(new QualifiedName(SYNC_KEY_QUALIFIER, id)); - } - - public IRemoteResource getRemoteResource(IResource resource) throws TeamException { - byte[] remoteBytes = getSyncBytes(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 = getSyncBytes(resource.getParent()); - if (parentBytes == null) { - CVSProviderPlugin.log(new CVSException( - Policy.bind("ResourceSynchronizer.missingParentBytesOnGet", getSyncName().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); - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ccvs.core.syncinfo.RemoteSynchronizer#setSyncBytes(org.eclipse.core.resources.IResource, byte[]) - */ - public boolean setSyncBytes(IResource resource, byte[] bytes) throws TeamException { - boolean changed = super.setSyncBytes(resource, bytes); - if (resource.getType() == IResource.FILE && getSyncBytes(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 (getSyncBytes(resource.getParent()) != null); - } - - /** - * Return the sync bytes associated with the remote resource. A return - * value of null indicates that the remote resource does not exist. - */ - protected byte[] getRemoteSyncBytes(IResource local, IRemoteResource remote) throws TeamException { - if (remote != null) { - return ((RemoteResource)remote).getSyncBytes(); - } else { - return 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 new file mode 100644 index 000000000..e910a03f4 --- /dev/null +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/CVSSynchronizationCache.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.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.ccvs.core.CVSProviderPlugin; +import org.eclipse.team.internal.ccvs.core.Policy; + +/** + * Override PersistantResourceVariantTree to log an error + * if there are no parent bytes for a file. + */ +public class CVSSynchronizationCache extends PersistantResourceVariantTree { + + 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/DeferredResourceChangeHandler.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/DeferredResourceChangeHandler.java index 4f921b0c2..6f2a18abd 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/DeferredResourceChangeHandler.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/DeferredResourceChangeHandler.java @@ -15,9 +15,9 @@ import java.util.*; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.BackgroundEventHandler; import org.eclipse.team.internal.ccvs.core.Policy; import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer; +import org.eclipse.team.internal.core.BackgroundEventHandler; /** * This class handles resources changes that are reported in deltas @@ -25,24 +25,14 @@ import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer; */ public class DeferredResourceChangeHandler extends BackgroundEventHandler { + public DeferredResourceChangeHandler() { + super(Policy.bind("DeferredResourceChangeHandler.0"), Policy.bind("DeferredResourceChangeHandler.1")); //$NON-NLS-1$ //$NON-NLS-2$ + } + private static final int IGNORE_FILE_CHANGED = 1; private Set changedIgnoreFiles = new HashSet(); - /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.BackgroundEventHandler#getName() - */ - public String getName() { - return Policy.bind("DeferredResourceChangeHandler.0"); //$NON-NLS-1$ - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.BackgroundEventHandler#getErrorsTitle() - */ - public String getErrorsTitle() { - return Policy.bind("DeferredResourceChangeHandler.1"); //$NON-NLS-1$ - } - /* (non-Javadoc) * @see org.eclipse.team.core.subscribers.BackgroundEventHandler#processEvent(org.eclipse.team.core.subscribers.BackgroundEventHandler.Event, org.eclipse.core.runtime.IProgressMonitor) */ @@ -64,13 +54,13 @@ public class DeferredResourceChangeHandler extends BackgroundEventHandler { } public void ignoreFileChanged(IFile file) { - queueEvent(new Event(file, IGNORE_FILE_CHANGED, IResource.DEPTH_ZERO)); + queueEvent(new Event(file, IGNORE_FILE_CHANGED, IResource.DEPTH_ZERO), false); } /* (non-Javadoc) * @see org.eclipse.team.core.subscribers.BackgroundEventHandler#dispatchEvents() */ - protected void dispatchEvents() throws TeamException { + protected void dispatchEvents(IProgressMonitor monitor) throws TeamException { EclipseSynchronizer.getInstance().ignoreFilesChanged(getParents(changedIgnoreFiles)); changedIgnoreFiles.clear(); } diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/MergedSynchronizer.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/MergedSynchronizer.java deleted file mode 100644 index 089c10985..000000000 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/MergedSynchronizer.java +++ /dev/null @@ -1,49 +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.core.runtime.QualifiedName; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.RemoteBytesSynchronizer; -import org.eclipse.team.core.sync.IRemoteResource; - -/** - * This synchronizer keeps track of which resources have been merged. - * It is to be used only by the CVSMergeSubscriber. - */ -public class MergedSynchronizer extends RemoteBytesSynchronizer { - - public MergedSynchronizer(String id) { - super(new QualifiedName(CVSRemoteSynchronizer.SYNC_KEY_QUALIFIER, id)); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSynchronizer#getRemoteResource(org.eclipse.core.resources.IResource) - */ - public IRemoteResource getRemoteResource(IResource resource) throws TeamException { - throw new UnsupportedOperationException(); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.ResourceSynchronizer#refresh(org.eclipse.core.resources.IResource[], int, boolean, org.eclipse.core.runtime.IProgressMonitor) - */ - public IResource[] refresh(IResource resource, int depth, boolean cacheFileContentsHint, IProgressMonitor monitor) throws TeamException { - try { - monitor.beginTask(null, 100); - return new IResource[0]; - } finally { - monitor.done(); - } - } - -} diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/OptimizedRemoteSynchronizer.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/OptimizedRemoteSynchronizer.java deleted file mode 100644 index 8065edc0b..000000000 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/OptimizedRemoteSynchronizer.java +++ /dev/null @@ -1,84 +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.team.core.TeamException; -import org.eclipse.team.internal.ccvs.core.CVSTag; -import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource; -import org.eclipse.team.internal.ccvs.core.util.Util; - -/** - * The optimized remote synchronizer uses the base sync info when the remote - * is unknown - */ -public class OptimizedRemoteSynchronizer extends RemoteTagSynchronizer { - - // The local synchronizer is used for cases where the remote is unknown - private BaseSynchronizer baseSynchronizer = new BaseSynchronizer(); - - public OptimizedRemoteSynchronizer(String id) { - this(id, null /* use the tag in the local workspace resources */); - } - - public OptimizedRemoteSynchronizer(String id, CVSTag tag) { - super(id, tag); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSynchronizer#getSyncBytes(org.eclipse.core.resources.IResource) - */ - public byte[] getSyncBytes(IResource resource) throws TeamException { - byte[] bytes = internalGetSyncBytes(resource); - if ((bytes == null) && !isRemoteKnown(resource)) { - // The remote was never known so use the base - bytes = baseSynchronizer.getSyncBytes(resource); - } - return bytes; - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ccvs.core.syncinfo.RemoteSynchronizer#setSyncBytes(org.eclipse.core.resources.IResource, byte[]) - */ - public boolean setSyncBytes(IResource resource, byte[] bytes) throws TeamException { - byte[] baseBytes = baseSynchronizer.getSyncBytes(resource); - if (baseBytes != null && Util.equals(baseBytes, bytes)) { - // Remove the existing bytes so the base will be used (thus saving space) - return removeSyncBytes(resource, IResource.DEPTH_ZERO); - } else { - return super.setSyncBytes(resource, bytes); - } - } - - public BaseSynchronizer getBaseSynchronizer() { - return baseSynchronizer; - } - - /* - * Return the bytes for the remote resource if there is a remote that differs - * from the local. - */ - private byte[] internalGetSyncBytes(IResource resource) throws TeamException { - return super.getSyncBytes(resource); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ccvs.core.syncinfo.RemoteTagSynchronizer#getRemoteSyncBytes(org.eclipse.core.resources.IResource, org.eclipse.team.internal.ccvs.core.ICVSRemoteResource) - */ - protected byte[] getRemoteSyncBytes(IResource local, ICVSRemoteResource remote) throws TeamException { - if (remote == null && local.getType() == IResource.FOLDER) { - // If there is no remote, use the local sync for the folder - return baseSynchronizer.getSyncBytes(local); - } - return super.getRemoteSyncBytes(local, remote); - } - -} diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ReentrantLock.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ReentrantLock.java index 9003195f7..fbae8d65e 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ReentrantLock.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ReentrantLock.java @@ -78,8 +78,8 @@ public class ReentrantLock { if (rule != NULL_SCHEDULING_RULE) { try { Platform.getJobManager().beginRule(rule, monitor); - } catch (OperationCanceledException e) { - // The begin was cancelled. + } catch (RuntimeException e) { + // The begin was cancelled (or some other problem occurred). // Free the scheduling rule and throw the cancel // so the clients of ReentrantLock don't need to // do an endRule when the operation is cancelled. diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/RemoteResourceFactory.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/RemoteResourceFactory.java deleted file mode 100644 index 21518f888..000000000 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/RemoteResourceFactory.java +++ /dev/null @@ -1,21 +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; - -/** - * @author Administrator - * - * To change the template for this generated type comment go to - * Window>Preferences>Java>Code Generation>Code and Comments - */ -public class RemoteResourceFactory { - -} diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/RemoteTagSynchronizer.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/RemoteTagSynchronizer.java deleted file mode 100644 index 30e547230..000000000 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/RemoteTagSynchronizer.java +++ /dev/null @@ -1,257 +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 java.util.ArrayList; -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.internal.jobs.JobManager; -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.IRemoteResource; -import org.eclipse.team.internal.ccvs.core.CVSException; -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.ICVSResource; -import org.eclipse.team.internal.ccvs.core.Policy; -import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; -import org.eclipse.team.internal.ccvs.core.util.Assert; - -/** - * This RemoteSynchronizr uses a CVS Tag to fetch the remote tree - */ -public class RemoteTagSynchronizer extends CVSRemoteSynchronizer { - - private CVSTag tag; - - public RemoteTagSynchronizer(String id, CVSTag tag) { - super(id); - this.tag = tag; - } - - public void collectChanges(IResource local, IRemoteResource remote, Collection changedResources, int depth, IProgressMonitor monitor) throws TeamException { - byte[] remoteBytes = getRemoteSyncBytes(local, remote); - boolean changed; - if (remoteBytes == null) { - changed = setRemoteDoesNotExist(local); - } else { - changed = setSyncBytes(local, remoteBytes); - } - 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(); - IRemoteResource remoteChild = (IRemoteResource)children.get(localChild); - collectChanges(localChild, remoteChild, changedResources, - depth == IResource.DEPTH_INFINITE ? IResource.DEPTH_INFINITE : IResource.DEPTH_ZERO, - monitor); - } - - // Look for resources that have sync bytes but are not in the resources we care about - IResource[] resources = getChildrenWithSyncBytes(local); - for (int i = 0; i < resources.length; i++) { - IResource resource = resources[i]; - if (!children.containsKey(resource)) { - // These sync bytes are stale. Purge them - removeSyncBytes(resource, IResource.DEPTH_INFINITE); - changedResources.add(resource); - } - } - } - - protected Map mergedMembers(IResource local, IRemoteResource remote, IProgressMonitor progress) throws TeamException { - - // {IResource -> IRemoteResource} - Map mergedResources = new HashMap(); - - IRemoteResource[] remoteChildren = getRemoteChildren(remote, progress); - - IResource[] localChildren = getLocalChildren(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++) { - IRemoteResource 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; - - IRemoteResource remoteChild = - remoteSet != null ? (IRemoteResource) 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 IRemoteResource[] getRemoteChildren(IRemoteResource remote, IProgressMonitor progress) throws TeamException { - return remote != null ? remote.members(progress) : new IRemoteResource[0]; - } - - private IResource[] getLocalChildren(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; - } - - private IResource[] getChildrenWithSyncBytes(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 (internalGetSyncBytes(resource) != null) { - childrenWithSyncBytes.add(resource); - } - } - return (IResource[]) childrenWithSyncBytes.toArray( - new IResource[childrenWithSyncBytes.size()]); - } - } catch (CoreException e) { - throw CVSException.wrapException(e); - } - return new IResource[0]; - } - - private byte[] internalGetSyncBytes(IResource resource) throws TeamException { - return super.getSyncBytes(resource); - } - - /* - * Returns a handle to a non-existing resource. - */ - 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 IResource[] refresh(IResource resource, int depth, boolean cacheFileContentsHint, IProgressMonitor monitor) throws TeamException { - List changedResources = new ArrayList(); - ISchedulingRule rule = resource.getProject(); - monitor.beginTask(null, 100); - try { - // Get a scheduling rule on the project since CVS may obtain a lock higher then - // the resource itself. - JobManager.getInstance().beginRule(rule, monitor); - if (!resource.getProject().isAccessible()) { - // The project is closed so silently skip it - return new IResource[0]; - } - - monitor.setTaskName(Policy.bind("RemoteTagSynchronizer.0", resource.getFullPath().makeRelative().toString())); //$NON-NLS-1$ - - // build the remote tree only if an initial tree hasn't been provided - IRemoteResource tree = buildRemoteTree(resource, depth, cacheFileContentsHint, Policy.subMonitorFor(monitor, 70)); - - // update the known remote handles - IProgressMonitor sub = Policy.infiniteSubMonitorFor(monitor, 30); - try { - sub.beginTask(null, 64); - collectChanges(resource, tree, changedResources, depth, sub); - } finally { - sub.done(); - } - } finally { - JobManager.getInstance().endRule(rule); - monitor.done(); - } - IResource[] changes = (IResource[]) changedResources.toArray(new IResource[changedResources.size()]); - return changes; - } - - /** - * Build a remote tree for the given parameters. - */ - protected ICVSRemoteResource buildRemoteTree(IResource resource, int depth, boolean cacheFileContentsHint, IProgressMonitor monitor) throws TeamException { - // TODO: we are currently ignoring the depth parameter because the build remote tree is - // by default deep! - return CVSWorkspaceRoot.getRemoteTree(resource, tag, cacheFileContentsHint, monitor); - } - -} diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ResourceSyncInfo.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ResourceSyncInfo.java index e25608d96..5a0af476b 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ResourceSyncInfo.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ResourceSyncInfo.java @@ -41,7 +41,7 @@ import org.eclipse.team.internal.ccvs.core.util.Util; * D/src//// * * @see MutableResourceSyncInfo - * @see ICVSResource#getSyncInfo() + * @see ICVSResource#getSyncInfos() */ public class ResourceSyncInfo { diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileWriter.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileWriter.java index 774c30761..a0827a374 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileWriter.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileWriter.java @@ -89,6 +89,10 @@ public class SyncFileWriter { public static byte[][] readAllResourceSync(IContainer parent) throws CVSException { IFolder cvsSubDir = getCVSSubdirectory(parent); if (! cvsSubDir.exists()) return null; + + if (Policy.DEBUG_METAFILE_CHANGES) { + System.out.println("Reading Entries file for " + parent.getFullPath()); //$NON-NLS-1$ + } // process Entries file contents String[] entries = readLines(cvsSubDir.getFile(ENTRIES)); @@ -131,6 +135,9 @@ public class SyncFileWriter { public static void writeAllResourceSync(IContainer parent, byte[][] infos) throws CVSException { try { + if (Policy.DEBUG_METAFILE_CHANGES) { + System.out.println("Writing Entries file for folder " + parent.getFullPath()); //$NON-NLS-1$ + } IFolder cvsSubDir = createCVSSubdirectory(parent); // format file contents @@ -158,6 +165,10 @@ public class SyncFileWriter { IFolder cvsSubDir = getCVSSubdirectory(folder); if (! cvsSubDir.exists()) return null; + if (Policy.DEBUG_METAFILE_CHANGES) { + System.out.println("Reading Root/Repository files for " + folder.getFullPath()); //$NON-NLS-1$ + } + // check to make sure the the cvs folder is hidden if (!cvsSubDir.isTeamPrivateMember()) { try { @@ -177,10 +188,16 @@ public class SyncFileWriter { // read CVS/Tag String tag = readFirstLine(cvsSubDir.getFile(TAG)); + if (Policy.DEBUG_METAFILE_CHANGES && tag != null) { + System.out.println("Reading Tag file for " + folder.getFullPath()); //$NON-NLS-1$ + } CVSTag cvsTag = (tag != null) ? new CVSEntryLineTag(tag) : null; // read Entries.Static String staticDir = readFirstLine(cvsSubDir.getFile(STATIC)); + if (Policy.DEBUG_METAFILE_CHANGES && staticDir != null) { + System.out.println("Reading Static file for " + folder.getFullPath()); //$NON-NLS-1$ + } boolean isStatic = (staticDir != null); // return folder sync @@ -193,6 +210,9 @@ public class SyncFileWriter { */ public static void writeFolderSync(IContainer folder, FolderSyncInfo info) throws CVSException { try { + if (Policy.DEBUG_METAFILE_CHANGES) { + System.out.println("Writing Root/Respository files for " + folder.getFullPath()); //$NON-NLS-1$ + } IFolder cvsSubDir = createCVSSubdirectory(folder); // write CVS/Root @@ -204,9 +224,15 @@ public class SyncFileWriter { // write CVS/Tag IFile tagFile = cvsSubDir.getFile(TAG); if (info.getTag() != null) { + if (Policy.DEBUG_METAFILE_CHANGES) { + System.out.println("Writing Tag file for " + folder.getFullPath()); //$NON-NLS-1$ + } writeLines(tagFile, new String[] {info.getTag().toEntryLineFormat(false)}); } else { if(tagFile.exists()) { + if (Policy.DEBUG_METAFILE_CHANGES) { + System.out.println("Deleting Tag file for " + folder.getFullPath()); //$NON-NLS-1$ + } tagFile.delete(IResource.NONE, null); } } @@ -215,9 +241,15 @@ public class SyncFileWriter { IFile staticFile = cvsSubDir.getFile(STATIC); if(info.getIsStatic()) { // the existance of the file is all that matters + if (Policy.DEBUG_METAFILE_CHANGES) { + System.out.println("Writing Static file for " + folder.getFullPath()); //$NON-NLS-1$ + } writeLines(staticFile, new String[] {""}); //$NON-NLS-1$ } else { if(staticFile.exists()) { + if (Policy.DEBUG_METAFILE_CHANGES) { + System.out.println("Deleting Static file for " + folder.getFullPath()); //$NON-NLS-1$ + } staticFile.delete(IResource.NONE, null); } } @@ -251,6 +283,9 @@ public class SyncFileWriter { */ public static void deleteFolderSync(IContainer folder) throws CVSException { try { + if (Policy.DEBUG_METAFILE_CHANGES) { + System.out.println("Deleting CVS directory from " + folder.getFullPath()); //$NON-NLS-1$ + } getCVSSubdirectory(folder).delete(IResource.NONE, null); } catch(CoreException e) { throw CVSException.wrapException(e); diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/Util.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/Util.java index 4da23d585..ba67eef69 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/Util.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/Util.java @@ -409,6 +409,7 @@ public class Util { * @return boolean */ public static boolean equals(byte[] syncBytes, byte[] oldBytes) { + if (syncBytes == null || oldBytes == null) return syncBytes == oldBytes; if (syncBytes.length != oldBytes.length) return false; for (int i = 0; i < oldBytes.length; i++) { if (oldBytes[i] != syncBytes[i]) return false; -- cgit v1.2.3