diff options
author | Jean Michel-Lemieux | 2004-02-25 20:34:58 +0000 |
---|---|---|
committer | Jean Michel-Lemieux | 2004-02-25 20:34:58 +0000 |
commit | 4a1ca77df6f4238416a8715a8c35819611d5992a (patch) | |
tree | 03e4ed09e94442352cb8c3143df59d3b22725627 | |
parent | a650f9521c18cb3c840475358086bf5f4052a824 (diff) | |
download | eclipse.platform.team-4a1ca77df6f4238416a8715a8c35819611d5992a.tar.gz eclipse.platform.team-4a1ca77df6f4238416a8715a8c35819611d5992a.tar.xz eclipse.platform.team-4a1ca77df6f4238416a8715a8c35819611d5992a.zip |
SyncView API released to HEAD.
320 files changed, 10896 insertions, 16943 deletions
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(); @@ -153,24 +124,10 @@ public class CVSMergeSubscriber extends CVSSyncTreeSubscriber implements IResour } /* (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) @@ -110,89 +65,22 @@ public abstract class CVSSyncTreeSubscriber extends TeamSubscriber { } /* (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; @@ -677,19 +677,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;i<elements.length;i++) { - ((CVSRemoteSyncElement)elements[i]).makeOutgoing(Policy.monitorFor(null)); - } - } - - /** * @see ITeamProvider#move(IResource, IPath, IProgressMonitor) */ public void moved(IPath source, IResource resource, IProgressMonitor progress) throws TeamException { diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSWorkspaceSubscriber.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSWorkspaceSubscriber.java index 7feeaaec2..4be128a42 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSWorkspaceSubscriber.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSWorkspaceSubscriber.java @@ -13,33 +13,29 @@ package org.eclipse.team.internal.ccvs.core; import java.util.ArrayList; import java.util.List; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceVisitor; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.QualifiedName; +import org.eclipse.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.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.core.subscribers.ISubscriberChangeEvent; +import org.eclipse.team.core.subscribers.SubscriberChangeEvent; +import org.eclipse.team.core.synchronize.IResourceVariant; +import org.eclipse.team.core.synchronize.SyncInfo; import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; -import org.eclipse.team.internal.ccvs.core.syncinfo.OptimizedRemoteSynchronizer; -import org.eclipse.team.internal.ccvs.core.syncinfo.RemoteTagSynchronizer; -import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; +import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer; +import org.eclipse.team.internal.ccvs.core.syncinfo.*; import org.eclipse.team.internal.ccvs.core.util.ResourceStateChangeListeners; +import org.eclipse.team.internal.core.subscribers.caches.PersistantResourceVariantTree; +import org.eclipse.team.internal.core.subscribers.caches.ResourceVariantTree; +import org.eclipse.team.internal.ccvs.core.Policy; /** * CVSWorkspaceSubscriber */ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IResourceStateChangeListener { - private OptimizedRemoteSynchronizer remoteSynchronizer; + private ResourceVariantTree remoteSynchronizer; + private ResourceVariantTree baseSynchronizer; // qualified name for remote sync info private static final String REMOTE_RESOURCE_KEY = "remote-resource-key"; //$NON-NLS-1$ @@ -48,7 +44,10 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe super(id, name, description); // install sync info participant - remoteSynchronizer = new OptimizedRemoteSynchronizer(REMOTE_RESOURCE_KEY); + baseSynchronizer = new CVSBaseSynchronizationCache(); + remoteSynchronizer = new CVSDescendantSynchronizationCache( + baseSynchronizer, + new PersistantResourceVariantTree(new QualifiedName(SYNC_KEY_QUALIFIER, REMOTE_RESOURCE_KEY))); ResourceStateChangeListeners.getListener().addResourceStateChangeListener(this); } @@ -90,24 +89,25 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe try { if (resource.getType() == IResource.FILE && (resource.exists() || resource.isPhantom())) { - byte[] remoteBytes = remoteSynchronizer.getSyncBytes(resource); + byte[] remoteBytes = remoteSynchronizer.getBytes(resource); if (remoteBytes == null) { - if (remoteSynchronizer.isRemoteKnown(resource)) { + if (remoteSynchronizer.isVariantKnown(resource)) { // The remote is known not to exist. If the local resource is // managed then this information is stale - if (getBaseSynchronizer().hasRemote(resource)) { + if (getBaseSynchronizationCache().getBytes(resource) != null) { if (canModifyWorkspace) { - remoteSynchronizer.removeSyncBytes(resource, IResource.DEPTH_ZERO); + remoteSynchronizer.removeBytes(resource, IResource.DEPTH_ZERO); } else { // The revision comparison will handle the stale sync bytes + // TODO: Unless the remote is known not to exist (see bug 52936) } } } } else { - byte[] localBytes = remoteSynchronizer.getBaseSynchronizer().getSyncBytes(resource); + byte[] localBytes = baseSynchronizer.getBytes(resource); if (localBytes == null || !isLaterRevision(remoteBytes, localBytes)) { if (canModifyWorkspace) { - remoteSynchronizer.removeSyncBytes(resource, IResource.DEPTH_ZERO); + remoteSynchronizer.removeBytes(resource, IResource.DEPTH_ZERO); } else { // The getRemoteResource method handles the stale sync bytes } @@ -115,8 +115,8 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe } } else if (resource.getType() == IResource.FOLDER) { // If the base has sync info for the folder, purge the remote bytes - if (getBaseSynchronizer().hasRemote(resource) && canModifyWorkspace) { - remoteSynchronizer.removeSyncBytes(resource, IResource.DEPTH_ZERO); + if (getBaseSynchronizationCache().getBytes(resource) != null && canModifyWorkspace) { + remoteSynchronizer.removeBytes(resource, IResource.DEPTH_ZERO); } } } catch (TeamException e) { @@ -124,7 +124,7 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe } } - fireTeamResourceChange(TeamDelta.asSyncChangedDeltas(this, changedResources)); + fireTeamResourceChange(SubscriberChangeEvent.asSyncChangedDeltas(this, changedResources)); } private boolean isLaterRevision(byte[] remoteBytes, byte[] localBytes) { @@ -159,8 +159,8 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe * @see org.eclipse.team.internal.ccvs.core.IResourceStateChangeListener#projectConfigured(org.eclipse.core.resources.IProject) */ public void projectConfigured(IProject project) { - TeamDelta delta = new TeamDelta(this, TeamDelta.PROVIDER_CONFIGURED, project); - fireTeamResourceChange(new TeamDelta[] {delta}); + SubscriberChangeEvent delta = new SubscriberChangeEvent(this, ISubscriberChangeEvent.ROOT_ADDED, project); + fireTeamResourceChange(new SubscriberChangeEvent[] {delta}); } /* (non-Javadoc) @@ -168,48 +168,82 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe */ public void projectDeconfigured(IProject project) { try { - remoteSynchronizer.removeSyncBytes(project, IResource.DEPTH_INFINITE); + remoteSynchronizer.removeBytes(project, IResource.DEPTH_INFINITE); } catch (TeamException e) { CVSProviderPlugin.log(e); } - TeamDelta delta = new TeamDelta(this, TeamDelta.PROVIDER_DECONFIGURED, project); - fireTeamResourceChange(new TeamDelta[] {delta}); + SubscriberChangeEvent delta = new SubscriberChangeEvent(this, ISubscriberChangeEvent.ROOT_REMOVED, project); + fireTeamResourceChange(new SubscriberChangeEvent[] {delta}); + } + + public void setRemote(IProject project, IResourceVariant remote, IProgressMonitor monitor) throws TeamException { + // TODO: This exposes internal behavior to much + IResource[] changedResources = + new CVSRefreshOperation(remoteSynchronizer, baseSynchronizer, null, false).collectChanges(project, remote, IResource.DEPTH_INFINITE, monitor); + if (changedResources.length != 0) { + fireTeamResourceChange(SubscriberChangeEvent.asSyncChangedDeltas(this, changedResources)); + } + } + + protected IResource[] refreshBase(IResource[] resources, int depth, 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.CVSSyncTreeSubscriber#getRemoteSynchronizer() + * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getRemoteTag() */ - protected RemoteSynchronizer getRemoteSynchronizer() { - return remoteSynchronizer; + protected CVSTag getRemoteTag() { + return null; } /* (non-Javadoc) - * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getBaseSynchronizer() + * @see org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber#getBaseTag() */ - protected RemoteSynchronizer getBaseSynchronizer() { - return remoteSynchronizer.getBaseSynchronizer(); + protected CVSTag getBaseTag() { + return null; + } + + /* (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; } /* (non-Javadoc) * @see org.eclipse.team.core.sync.TeamSubscriber#getAllOutOfSync(org.eclipse.core.resources.IResource[], int, org.eclipse.core.runtime.IProgressMonitor) */ - public SyncInfo[] getAllOutOfSync(IResource[] resources, final int depth, IProgressMonitor monitor) throws TeamException { - monitor.beginTask(null, resources.length * 100); + public SyncInfo[] getAllOutOfSync(IResource[] resources, final int depth, final IProgressMonitor monitor) throws TeamException { + monitor.beginTask(null, IProgressMonitor.UNKNOWN); final List result = new ArrayList(); for (int i = 0; i < resources.length; i++) { IResource resource = resources[i]; - final IProgressMonitor infinite = Policy.infiniteSubMonitorFor(monitor, 100); try { // We need to do a scheduling rule on the project to // avoid overly desctructive operations from occuring // while we gather sync info - infinite.beginTask(null, 512); - Platform.getJobManager().beginRule(resource, Policy.subMonitorFor(infinite, 1)); + Platform.getJobManager().beginRule(resource, monitor); resource.accept(new IResourceVisitor() { public boolean visit(IResource innerResource) throws CoreException { try { - if (isOutOfSync(innerResource, infinite)) { - SyncInfo info = getSyncInfo(innerResource, infinite); + if (innerResource.getType() != IResource.FILE) { + monitor.subTask(Policy.bind("CVSWorkspaceSubscriber.1", innerResource.getFullPath().toString())); //$NON-NLS-1$ + } + if (isOutOfSync(innerResource, monitor)) { + SyncInfo info = getSyncInfo(innerResource); if (info != null && info.getKind() != 0) { result.add(info); } @@ -225,7 +259,7 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe throw CVSException.wrapException(e); } finally { Platform.getJobManager().endRule(resource); - infinite.done(); + monitor.done(); } } monitor.done(); @@ -233,59 +267,32 @@ public class CVSWorkspaceSubscriber extends CVSSyncTreeSubscriber implements IRe } /* internal use only */ boolean isOutOfSync(IResource resource, IProgressMonitor monitor) throws TeamException { - return (hasIncomingChange(resource) || hasOutgoingChange(CVSWorkspaceRoot.getCVSResourceFor(resource), monitor)); - } - - private boolean hasOutgoingChange(ICVSResource resource, IProgressMonitor monitor) throws CVSException { - if (resource.isFolder()) { - // A folder is an outgoing change if it is not a CVS folder and not ignored - ICVSFolder folder = (ICVSFolder)resource; - // OPTIMIZE: The following checks load the CVS folder information - if (folder.getParent().isModified(monitor)) { - return !folder.isCVSFolder() && !folder.isIgnored(); - } - } else { - // A file is an outgoing change if it is modified - ICVSFile file = (ICVSFile)resource; - // The parent caches the dirty state so we only need to check - // the file if the parent is dirty - // OPTIMIZE: Unfortunately, the modified check on the parent still loads - // the CVS folder information so not much is gained - if (file.getParent().isModified(monitor)) { - return file.isModified(monitor); - } - } - return false; + return (hasIncomingChange(resource) || hasOutgoingChange(resource, monitor)); } private boolean hasIncomingChange(IResource resource) throws TeamException { - return remoteSynchronizer.isRemoteKnown(resource); + return remoteSynchronizer.isVariantKnown(resource); } - - /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.TeamSubscriber#getRemoteResource(org.eclipse.core.resources.IResource) - */ - public IRemoteResource getRemoteResource(IResource resource) throws TeamException { - IRemoteResource remote = super.getRemoteResource(resource); - if (resource.getType() == IResource.FILE && remote instanceof ICVSRemoteFile) { - byte[] remoteBytes = ((ICVSRemoteFile)remote).getSyncBytes(); - byte[] localBytes = CVSWorkspaceRoot.getCVSFileFor((IFile)resource).getSyncBytes(); - if (localBytes != null && remoteBytes != null) { - if (!ResourceSyncInfo.isLaterRevisionOnSameBranch(remoteBytes, localBytes)) { - // The remote bytes are stale so ignore the remote and use the base - return getBaseResource(resource); - } - } + + private boolean hasOutgoingChange(IResource resource, IProgressMonitor monitor) throws CVSException { + if (resource.getType() == IResource.PROJECT || resource.getType() == IResource.ROOT) { + // a project (or the workspace root) cannot have outgoing changes + return false; } - return remote; - } - - public void setRemote(IProject project, IRemoteResource remote, IProgressMonitor monitor) throws TeamException { - List changedResources = new ArrayList(); - ((RemoteTagSynchronizer)getRemoteSynchronizer()).collectChanges(project, remote, changedResources, IResource.DEPTH_INFINITE, monitor); - if (!changedResources.isEmpty()) { - IResource[] changes = (IResource[]) changedResources.toArray(new IResource[changedResources.size()]); - fireTeamResourceChange(TeamDelta.asSyncChangedDeltas(this, changes)); + int state = EclipseSynchronizer.getInstance().getModificationState(resource.getParent()); + if (state == ICVSFile.CLEAN) { + // if the parent is known to be clean then the resource must also be clean + return false; + } + if (resource.getType() == IResource.FILE) { + // A file is an outgoing change if it is modified + ICVSFile file = CVSWorkspaceRoot.getCVSFileFor((IFile)resource); + return file.isModified(monitor); + } else { + // A folder is an outgoing change if it is not a CVS folder and not ignored + ICVSFolder folder = CVSWorkspaceRoot.getCVSFolderFor((IContainer)resource); + return !folder.isCVSFolder() && !folder.isIgnored(); } } + } diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSRemoteFile.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSRemoteFile.java index fd0e29abc..61c1916cb 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSRemoteFile.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSRemoteFile.java @@ -11,6 +11,8 @@ package org.eclipse.team.internal.ccvs.core; +import java.io.InputStream; + import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.team.core.TeamException; @@ -26,6 +28,14 @@ import org.eclipse.team.core.TeamException; public interface ICVSRemoteFile extends ICVSRemoteResource, ICVSFile { /** + * Returns a stream over the contents of this remote element. + * + * @param progress a progress monitor to indicate the duration of the operation, or + * <code>null</code> 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) * method is called (i.e. the call to getContents also fetches the entry. 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 <code>true</code> if the remote element may have children and + * <code>false</code> 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 * <code>null</code> 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 @@ -323,18 +285,6 @@ public class RemoteFile extends RemoteResource implements ICVSRemoteFile { } /** - * @see ICVSFile#getSize() - */ - public long getSize() { - if (fetching) return 0; - RemoteContentsCacheEntry entry = getCacheEntry(); - if (entry == null) { - return 0; - } - return entry.getSize(); - } - - /** * @see ICVSFile#getSyncInfo() */ public ResourceSyncInfo 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 <code>null</code> 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 <code>PersistantResourceVariantTree</code> 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,25 +25,15 @@ 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) */ protected void processEvent(Event event, IProgressMonitor monitor) throws TeamException { @@ -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; diff --git a/bundles/org.eclipse.team.cvs.ui/.project b/bundles/org.eclipse.team.cvs.ui/.project index 7abb228e6..2e8b0ec7f 100644 --- a/bundles/org.eclipse.team.cvs.ui/.project +++ b/bundles/org.eclipse.team.cvs.ui/.project @@ -4,7 +4,6 @@ <comment></comment> <projects> <project>org.eclipse.compare</project> - <project>org.eclipse.core.boot</project> <project>org.eclipse.core.resources</project> <project>org.eclipse.core.resources.spysupport</project> <project>org.eclipse.core.runtime</project> diff --git a/bundles/org.eclipse.team.cvs.ui/icons/full/cview16/compare_view.gif b/bundles/org.eclipse.team.cvs.ui/icons/full/cview16/compare_view.gif Binary files differnew file mode 100644 index 000000000..41800a0c9 --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/icons/full/cview16/compare_view.gif diff --git a/bundles/org.eclipse.team.cvs.ui/icons/full/obj16/day_obj.gif b/bundles/org.eclipse.team.cvs.ui/icons/full/obj16/day_obj.gif Binary files differnew file mode 100644 index 000000000..96aae05cb --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/icons/full/obj16/day_obj.gif diff --git a/bundles/org.eclipse.team.cvs.ui/plugin.properties b/bundles/org.eclipse.team.cvs.ui/plugin.properties index 2d318bae3..3f2b971cb 100644 --- a/bundles/org.eclipse.team.cvs.ui/plugin.properties +++ b/bundles/org.eclipse.team.cvs.ui/plugin.properties @@ -21,6 +21,7 @@ SharingWizard.name=CVS CVSWorkspaceParticipant=CVS Workspace CVSMergeParticipant=CVS Merge +CVSCompareParticipant=CVS Compare PreferencePage.name=CVS ConsolePreferencePage.name=Console @@ -121,7 +122,7 @@ OpenRemoteFileAction.tooltip=Open Remote File ShowHistoryAction.label=Show in Resource &History ShowHistoryAction.tooltip=Show in Resource History -ShowAnnotationAction.label=Show Annotation +ShowAnnotationAction.label=Show &Annotation ShowAnnotationAction.tooltip=Show Annotation GenerateDiff.label=Create &Patch... @@ -190,5 +191,8 @@ CVSWorkspaceSubscriber.confirmMerged.tooltip=Mark the conflict as merged by upgr CVSWorkspaceSubscriber.merge.label=&Update CVSWorkspaceSubscriber.merge.tooltip=Perform an update merge on the visible resources +CVSCompareSubscriber.revert.label=Re&vert Local to Remote +CVSCompareSubscriber.revert.tooltip=Revert the local file contents to match that of their corresponding remotes + WorkInProgress.name=Work In Progress CVSRemoteQuickDiffProvider.label=Latest CVS Revision
\ No newline at end of file diff --git a/bundles/org.eclipse.team.cvs.ui/plugin.xml b/bundles/org.eclipse.team.cvs.ui/plugin.xml index 5ffd111a1..b1bd8d7e1 100644 --- a/bundles/org.eclipse.team.cvs.ui/plugin.xml +++ b/bundles/org.eclipse.team.cvs.ui/plugin.xml @@ -47,6 +47,13 @@ type="dynamic" id="org.eclipse.team.cvs.ui.cvsmerge-participant"> </participant> + <participant + name="%CVSCompareParticipant" + icon="icons/full/cview16/compare_view.gif" + class="org.eclipse.team.internal.ccvs.ui.subscriber.CompareSynchronizeParticipant" + type="dynamic" + id="org.eclipse.team.cvs.ui.compare-participant"> + </participant> </extension> <!-- *************** Authenticator **************** --> @@ -262,14 +269,6 @@ menubarPath="compareWithMenu/compareWithGroup" helpContextId="org.eclipse.team.cvs.ui.compare_with_tag_action_context" id="org.eclipse.team.ccvs.ui.compareWithTag"> - </action> - <action - label="%CompareWithRemoteAction.label" - tooltip="%CompareWithRemoteAction.tooltip" - class="org.eclipse.team.internal.ccvs.ui.actions.CompareWithRemoteAction" - menubarPath="compareWithMenu/compareWithGroup" - helpContextId="org.eclipse.team.cvs.ui.compare_with_latest_action_context" - id="org.eclipse.team.ccvs.ui.compareWithRemote"> </action> <action label="%ReplaceWithTagAction.label" @@ -721,6 +720,37 @@ id="org.eclipse.team.ccvs.ui.showAnnotation"> </action> </viewerContribution> + + <viewerContribution + id="org.eclipse.team.ccvs.ui.CVSCompareSubscriberContributions" + targetID="org.eclipse.team.cvs.ui.compare-participant"> + <action + label="%CVSCompareSubscriber.revert.label" + menubarPath="SubscriberActionsGroup1" + tooltip="%CVSCompareSubscriber.revert.tooltip" + class="org.eclipse.team.internal.ccvs.ui.subscriber.CompareRevertAction" + helpContextId="org.eclipse.team.cvs.ui.compare_revert_action" + id="org.eclipse.team.ccvs.ui.CVSCompareSubscriber.revert"> + </action> + <action + label="%ShowHistoryAction.label" + tooltip="%ShowHistoryAction.tooltip" + icon="icons/full/ctool16/history.gif" + class="org.eclipse.team.internal.ccvs.ui.actions.ShowResourceInHistoryAction" + menubarPath="SubscriberActionsGroup3" + helpContextId="org.eclipse.team.cvs.ui.show_in_history_action_context" + id="org.eclipse.team.ccvs.ui.showHistory"> + </action> + <action + label="%ShowAnnotationAction.label" + tooltip="%ShowAnnotationAction.tooltip" + icon="icons/full/ctool16/annotate.gif" + class="org.eclipse.team.internal.ccvs.ui.actions.ShowAnnotationAction" + menubarPath="SubscriberActionsGroup3" + helpContextId="org.eclipse.team.cvs.ui.get_annotate_action_context" + id="org.eclipse.team.ccvs.ui.showAnnotation"> + </action> + </viewerContribution> </extension> <!-- ************** Views ********************** --> @@ -892,26 +922,6 @@ <projectSet id="org.eclipse.team.cvs.core.cvsnature" class="org.eclipse.team.internal.ccvs.ui.CVSProjectSetSerializer"/> </extension> - - <!-- ************ Editor Actions ************** --> - <extension point="org.eclipse.ui.editorActions"> - <editorContribution - id="org.eclipse.team.cvs.ui.contentCompare" - targetID="org.eclipse.compare.CompareEditor"> - <action - id="org.eclipse.team.cvs.ui.ContentAction" - state="false" - toolbarPath="Normal/additions" - icon="icons/full/etool16/contents.gif" - disabledIcon="icons/full/dtool16/contents.gif" - hoverIcon="icons/full/ctool16/contents.gif" - label="%ContentAction.label" - tooltip="%ContentAction.tooltip" - class="org.eclipse.team.internal.ccvs.ui.actions.ContentAction"> - </action> - </editorContribution> - </extension> - <!-- ********** Action Sets ************** --> <extension point="org.eclipse.ui.actionSets"> <actionSet diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSCompareRevisionsInput.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSCompareRevisionsInput.java index 2b6087f67..085dd4e3a 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSCompareRevisionsInput.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSCompareRevisionsInput.java @@ -15,44 +15,20 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; -import org.eclipse.compare.CompareConfiguration; -import org.eclipse.compare.CompareEditorInput; -import org.eclipse.compare.CompareUI; -import org.eclipse.compare.ITypedElement; -import org.eclipse.compare.ResourceNode; -import org.eclipse.compare.structuremergeviewer.DiffContainer; -import org.eclipse.compare.structuremergeviewer.DiffNode; -import org.eclipse.compare.structuremergeviewer.Differencer; +import org.eclipse.compare.*; +import org.eclipse.compare.structuremergeviewer.*; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IMenuListener; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.MenuManager; +import org.eclipse.core.runtime.*; +import org.eclipse.jface.action.*; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Table; +import org.eclipse.jface.viewers.*; +import org.eclipse.swt.widgets.*; import org.eclipse.team.core.RepositoryProvider; import org.eclipse.team.core.TeamException; -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.ICVSRemoteFile; -import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource; -import org.eclipse.team.internal.ccvs.core.ILogEntry; +import org.eclipse.team.core.synchronize.IResourceVariant; +import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.core.client.Command; import org.eclipse.team.internal.ccvs.core.client.Update; import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; @@ -280,12 +256,12 @@ public class CVSCompareRevisionsInput extends CompareEditorInput { if (selection.size() != 1) return; VersionCompareDiffNode node = (VersionCompareDiffNode)selection.getFirstElement(); ResourceEditionNode right = (ResourceEditionNode)node.getRight(); - ICVSRemoteResource edition = right.getRemoteResource(); + IResourceVariant edition = (IResourceVariant)right.getRemoteResource(); // Do the load. This just consists of setting the local contents. We don't // actually want to change the base. try { monitor.beginTask(null, 100); - InputStream in = edition.getContents(new SubProgressMonitor(monitor, 50)); + InputStream in = edition.getStorage(new SubProgressMonitor(monitor, 50)).getContents(); resource.setContents(in, false, true, new SubProgressMonitor(monitor, 50)); } catch (TeamException e) { throw new InvocationTargetException(e); diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSLightweightDecorator.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSLightweightDecorator.java index 3f95dfa6d..335660518 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSLightweightDecorator.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSLightweightDecorator.java @@ -59,7 +59,7 @@ import org.eclipse.team.ui.TeamUI; public class CVSLightweightDecorator extends LabelProvider implements ILightweightLabelDecorator, IResourceStateChangeListener, IPropertyChangeListener { // Decorator id as defined in the decorator extension point - public final static String ID = "org.eclipse.team.cvs.ui.decorator"; + public final static String ID = "org.eclipse.team.cvs.ui.decorator"; //$NON-NLS-1$ // Images cached for better performance private static ImageDescriptor dirty; diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSLocalCompareEditorInput.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSLocalCompareEditorInput.java deleted file mode 100644 index efef0f332..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSLocalCompareEditorInput.java +++ /dev/null @@ -1,88 +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.ui; - - -import org.eclipse.compare.structuremergeviewer.ICompareInput; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.IRemoteResource; -import org.eclipse.team.core.sync.IRemoteSyncElement; -import org.eclipse.team.internal.ccvs.core.CVSTag; -import org.eclipse.team.internal.ccvs.core.resources.CVSRemoteSyncElement; -import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; -import org.eclipse.team.internal.ccvs.core.util.Assert; -import org.eclipse.team.internal.ccvs.ui.sync.CVSSyncCompareInput; -import org.eclipse.team.internal.ui.sync.SyncView; - -public class CVSLocalCompareEditorInput extends CVSSyncCompareInput { - CVSTag[] tags; - - public CVSLocalCompareEditorInput(IResource[] resources, CVSTag[] tags) { - super(resources); - Assert.isTrue(resources.length == tags.length); - this.tags = tags; - } - - public CVSLocalCompareEditorInput(IResource[] resources, CVSTag tag) { - super(resources); - Assert.isTrue(tag != null); - this.tags = new CVSTag[] {tag}; - } - - public Viewer createDiffViewer(Composite parent) { - Viewer viewer = super.createDiffViewer(parent); - getViewer().syncModeChanged(SyncView.SYNC_COMPARE); - return viewer; - } - - protected IRemoteSyncElement[] createSyncElements(IProgressMonitor monitor) throws TeamException { - IResource[] resources = getResources(); - IRemoteSyncElement[] trees = new IRemoteSyncElement[resources.length]; - int work = 100 * resources.length; - monitor.beginTask(null, work); - try { - for (int i = 0; i < trees.length; i++) { - IResource resource = resources[i]; - CVSTag tag; - if(tags.length != resources.length) { - tag = tags[0]; - } else { - tag = tags[i]; - } - IRemoteResource remote = CVSWorkspaceRoot.getRemoteTree(resource, tag, getCacheFileContentsHint(), Policy.subMonitorFor(monitor, 50)); - trees[i] = new CVSRemoteSyncElement(false /* two-way */, resource, null, remote); - } - } finally { - monitor.done(); - } - //getViewer().resetFilters(); - return trees; - } - - private boolean getCacheFileContentsHint() { - return getSyncGranularity() != IRemoteSyncElement.GRANULARITY_TIMESTAMP; - } - - public String getTitle() { - return Policy.bind("CVSLocalCompareEditorInput.title", tags[0].getName()); //$NON-NLS-1$ - } - - protected void contentsChanged(ICompareInput source) { - } - - public String getToolTipText() { - return getTitle(); - } -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSUIPlugin.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSUIPlugin.java index bacde420c..443e4708d 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSUIPlugin.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSUIPlugin.java @@ -408,6 +408,7 @@ public class CVSUIPlugin extends AbstractUIPlugin { createImageDescriptor(ICVSUIConstants.IMG_EDITED, baseURL); createImageDescriptor(ICVSUIConstants.IMG_NO_REMOTEDIR, baseURL); createImageDescriptor(ICVSUIConstants.IMG_CVS_CONSOLE, baseURL); + createImageDescriptor(ICVSUIConstants.IMG_DATE, baseURL); // special createImageDescriptor("glyphs/glyph1.gif", baseURL); //$NON-NLS-1$ @@ -731,12 +732,11 @@ public class CVSUIPlugin extends AbstractUIPlugin { * @param workingSet the working set to be assigned to the participant (can be <code>null</code>) * @param mode the mode to place the participant in (can be 0) */ - public static void showInSyncView(Shell shell, IResource[] resources, IWorkingSet workingSet, int mode) { + public static void showInSyncView(Shell shell, IResource[] resources, int mode) { ISynchronizeView view = TeamUI.getSynchronizeManager().showSynchronizeViewInActivePage(null); if(view != null) { WorkspaceSynchronizeParticipant cvsPage = CVSUIPlugin.getPlugin().getCvsWorkspaceSynchronizeParticipant(); view.display(cvsPage); - cvsPage.setWorkingSet(workingSet); if (resources != null) { cvsPage.refreshWithRemote(resources); } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CommitCommentArea.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CommitCommentArea.java index 430c19c53..9fb2e0fe5 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CommitCommentArea.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CommitCommentArea.java @@ -39,7 +39,7 @@ import org.eclipse.team.internal.ui.dialogs.DialogArea; public class CommitCommentArea extends DialogArea { private static final int WIDTH_HINT = 350; - private static final int HEIGHT_HINT = 150; + private static final int HEIGHT_HINT = 50; private Text text; private Combo previousCommentsCombo; diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/HistoryView.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/HistoryView.java index 1718bb376..76cc66ab9 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/HistoryView.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/HistoryView.java @@ -16,92 +16,37 @@ import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Iterator; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.QualifiedName; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IMenuListener; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.core.resources.*; +import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.jobs.*; +import org.eclipse.jface.action.*; +import org.eclipse.jface.dialogs.*; import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.text.Document; -import org.eclipse.jface.text.ITextOperationTarget; -import org.eclipse.jface.text.TextViewer; -import org.eclipse.jface.viewers.ColumnWeightData; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.TableLayout; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.jface.text.*; +import org.eclipse.jface.viewers.*; import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.BusyIndicator; -import org.eclipse.swt.custom.SashForm; -import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.custom.*; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.*; import org.eclipse.team.core.RepositoryProvider; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin; -import org.eclipse.team.internal.ccvs.core.CVSSyncInfo; -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.ICVSRemoteFile; -import org.eclipse.team.internal.ccvs.core.ICVSResource; -import org.eclipse.team.internal.ccvs.core.ILogEntry; +import org.eclipse.team.core.synchronize.SyncInfo; +import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.core.client.Command; import org.eclipse.team.internal.ccvs.core.client.Update; import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; -import org.eclipse.team.internal.ccvs.ui.actions.CVSAction; -import org.eclipse.team.internal.ccvs.ui.actions.MoveRemoteTagAction; -import org.eclipse.team.internal.ccvs.ui.actions.OpenLogEntryAction; +import org.eclipse.team.internal.ccvs.ui.actions.*; import org.eclipse.team.internal.ui.jobs.JobBusyCursor; -import org.eclipse.team.internal.ui.jobs.JobStatusHandler; -import org.eclipse.team.internal.ui.synchronize.compare.SyncInfoCompareInput; -import org.eclipse.ui.IActionBars; -import org.eclipse.ui.IActionDelegate; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IFileEditorInput; -import org.eclipse.ui.IPartListener; -import org.eclipse.ui.IPartListener2; -import org.eclipse.ui.IWorkbenchActionConstants; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchPartReference; -import org.eclipse.ui.PartInitException; +import org.eclipse.team.ui.synchronize.viewers.SyncInfoCompareInput; +import org.eclipse.ui.*; import org.eclipse.ui.actions.WorkspaceModifyOperation; import org.eclipse.ui.help.WorkbenchHelp; import org.eclipse.ui.part.ResourceTransfer; import org.eclipse.ui.part.ViewPart; +import org.eclipse.ui.progress.IWorkbenchSiteProgressService; import org.eclipse.ui.texteditor.ITextEditorActionConstants; /** @@ -141,7 +86,7 @@ public class HistoryView extends ViewPart { private IPreferenceStore settings; private FetchLogEntriesJob fetchLogEntriesJob; - private JobBusyCursor jobBusyCursor; + private JobBusyCursor halfBusyCursor; private boolean shutdown = false; @@ -439,13 +384,11 @@ public class HistoryView extends ViewPart { contributeActions(); setViewerVisibility(); + halfBusyCursor = new JobBusyCursor(parent); // set F1 help WorkbenchHelp.setHelp(sashForm, IHelpContextIds.RESOURCE_HISTORY_VIEW); initDragAndDrop(); - - // Create the busy cursor with no control to start with (createViewer will set it) - jobBusyCursor = new JobBusyCursor(parent, HISTORY_VIEW_JOB_TYPE); // add listener for editor page activation - this is to support editor linking getSite().getPage().addPartListener(partListener); @@ -488,7 +431,7 @@ public class HistoryView extends ViewPart { } } fetchLogEntriesJob.setRemoteFile(remoteFile); - JobStatusHandler.schedule(fetchLogEntriesJob, HISTORY_VIEW_JOB_TYPE); + schedule(fetchLogEntriesJob); return new Object[0]; } public void dispose() { @@ -592,14 +535,13 @@ public class HistoryView extends ViewPart { try { fetchLogEntriesJob.join(); } catch (InterruptedException e) { - CVSUIPlugin.log(new CVSException(Policy.bind("HistoryView.errorFetchingEntries", ""), e)); //$NON-NLS-1$ + CVSUIPlugin.log(new CVSException(Policy.bind("HistoryView.errorFetchingEntries", ""), e)); //$NON-NLS-1$ //$NON-NLS-2$ } } } - + halfBusyCursor.dispose(); getSite().getPage().removePartListener(partListener); getSite().getPage().removePartListener(partListener2); - jobBusyCursor.dispose(); } /** * Returns the table viewer contained in this view. @@ -902,4 +844,33 @@ public class HistoryView extends ViewPart { private boolean isLinkingEnabled() { return linkingEnabled; } + + + private void schedule(Job job) { + IViewSite site = getViewSite(); + if(site != null) { + IWorkbenchSiteProgressService siteProgress = (IWorkbenchSiteProgressService)getViewSite().getAdapter(IWorkbenchSiteProgressService.class); + if(siteProgress != null) { + siteProgress.schedule(job); + return; + } + } + job.schedule(); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.WorkbenchPart#getJobChangeListener() + * Temporary until the following bug is fixed: + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=51991 + */ + public IJobChangeListener getJobChangeListener() { + return new JobChangeAdapter() { + public void done(IJobChangeEvent event) { + halfBusyCursor.finished(); + } + public void running(IJobChangeEvent event) { + halfBusyCursor.started(); + } + }; + } } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ICVSUIConstants.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ICVSUIConstants.java index 75856e6b1..bf8b42192 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ICVSUIConstants.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ICVSUIConstants.java @@ -34,6 +34,7 @@ public interface ICVSUIConstants { public final String IMG_VERSIONS_CATEGORY = "obj16/versions_rep.gif"; //$NON-NLS-1$ public final String IMG_MODULE = "obj16/module_rep.gif"; //$NON-NLS-1$ public final String IMG_PROJECT_VERSION = "obj16/prjversions_rep.gif"; //$NON-NLS-1$ + public final String IMG_DATE = "obj16/day_obj.gif"; //$NON-NLS-1$ // toolbar public final String IMG_REFRESH = "clcl16/refresh.gif"; //$NON-NLS-1$ diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/KeyboardInteractiveDialog.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/KeyboardInteractiveDialog.java index 00b16a5d8..e862c4af2 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/KeyboardInteractiveDialog.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/KeyboardInteractiveDialog.java @@ -59,7 +59,7 @@ public class KeyboardInteractiveDialog extends Dialog { this.instruction=instruction; this.prompt=prompt; this.echo=echo; - this.message=Policy.bind("KeyboradInteractiveDialog.message", destination+(name!=null && name.length()>0 ? ": "+name : "")); //NON-NLS-1$ + this.message=Policy.bind("KeyboradInteractiveDialog.message", destination+(name!=null && name.length()>0 ? ": "+name : "")); //NON-NLS-1$ //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } /** * @see Window#configureShell @@ -96,7 +96,7 @@ public class KeyboardInteractiveDialog extends Dialog { } if(domain!=null){ Label label = new Label(main, SWT.WRAP); - label.setText(Policy.bind("KeyboardInteractiveDialog.labelRepository", domain)); + label.setText(Policy.bind("KeyboardInteractiveDialog.labelRepository", domain)); //$NON-NLS-1$ GridData data=new GridData(GridData.FILL_HORIZONTAL); data.horizontalSpan=3; label.setLayoutData(data); diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ReleaseCommentDialog.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ReleaseCommentDialog.java index f870f30d0..974437a5f 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ReleaseCommentDialog.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ReleaseCommentDialog.java @@ -10,44 +10,82 @@ *******************************************************************************/ package org.eclipse.team.internal.ccvs.ui; +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.compare.CompareConfiguration; +import org.eclipse.compare.CompareEditorInput; import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.*; +import org.eclipse.team.core.synchronize.SyncInfo; +import org.eclipse.team.core.synchronize.SyncInfoTree; +import org.eclipse.team.internal.ui.Utils; +import org.eclipse.team.internal.ui.dialogs.DetailsDialog; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; +import org.eclipse.team.ui.synchronize.viewers.TreeViewerAdvisor; +import org.eclipse.team.ui.synchronize.viewers.SynchronizeCompareInput; import org.eclipse.ui.help.WorkbenchHelp; +import org.eclipse.ui.internal.dialogs.ContainerCheckedTreeViewer; /** * Prompts the user for a multi-line comment for releasing to CVS. */ -public class ReleaseCommentDialog extends Dialog { +public class ReleaseCommentDialog extends DetailsDialog { CommitCommentArea commitCommentArea; + // dialogs settings that are persistent between workbench sessions + private IDialogSettings settings; + private IResource[] resourcesToCommit; + private CompareEditorInput compareEditorInput; + private SyncInfoTree set; + private int depth; + private static final String HEIGHT_KEY = "width-key"; //$NON-NLS-1$ + private static final String WIDTH_KEY = "height-key"; //$NON-NLS-1$ /** * ReleaseCommentDialog constructor. * * @param parentShell the parent of this dialog */ - public ReleaseCommentDialog(Shell parentShell, IResource[] resourcesToCommit) { - super(parentShell); + public ReleaseCommentDialog(Shell parentShell, IResource[] resourcesToCommit, int depth) { + super(parentShell, Policy.bind("ReleaseCommentDialog.title")); //$NON-NLS-1$ + this.resourcesToCommit = resourcesToCommit; + this.depth = depth; int shellStyle = getShellStyle(); - setShellStyle(shellStyle | SWT.RESIZE); + setShellStyle(shellStyle | SWT.RESIZE | SWT.MAX); commitCommentArea = new CommitCommentArea(this, null); // Get a project from which the commit template can be obtained if (resourcesToCommit.length > 0) commitCommentArea.setProject(resourcesToCommit[0].getProject()); + + IDialogSettings workbenchSettings = CVSUIPlugin.getPlugin().getDialogSettings(); + this.settings = workbenchSettings.getSection("ReleaseCommentDialog");//$NON-NLS-1$ + if (settings == null) { + this.settings = workbenchSettings.addNewSection("ReleaseCommentDialog");//$NON-NLS-1$ + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.dialogs.DetailsDialog#includeDetailsButton() + */ + protected boolean includeDetailsButton() { + return false; } /* * @see Dialog#createDialogArea(Composite) */ - protected Control createDialogArea(Composite parent) { + protected void createMainDialogArea(Composite parent) { getShell().setText(Policy.bind("ReleaseCommentDialog.title")); //$NON-NLS-1$ Composite composite = new Composite(parent, SWT.NULL); composite.setLayout(new GridLayout()); @@ -64,16 +102,105 @@ public class ReleaseCommentDialog extends Dialog { // set F1 help WorkbenchHelp.setHelp(composite, IHelpContextIds.RELEASE_COMMENT_DIALOG); Dialog.applyDialogFont(parent); - - return composite; } - /** - * Returns the comment. - * @return String + private SyncInfoTree createResourcesToCommitSyncInfoSet(IResource[] resourcesToCommit) { + // Create a sync set containing only the resources that will be committed. + SubscriberParticipant participant = CVSUIPlugin.getPlugin().getCvsWorkspaceSynchronizeParticipant(); + SyncInfoTree currentSet = participant.getSubscriberSyncInfoCollector().getSyncInfoTree(); + SyncInfoTree set = new SyncInfoTree(); + for (int i = 0; i < resourcesToCommit.length; i++) { + IResource resource = resourcesToCommit[i]; + SyncInfo info = currentSet.getSyncInfo(resource); + if(info != null) { + set.add(info); + } + } + return set; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.window.Window#getInitialSize() */ + protected Point getInitialSize() { + int width, height; + try { + height = settings.getInt(HEIGHT_KEY); + width = settings.getInt(WIDTH_KEY); + } catch(NumberFormatException e) { + return super.getInitialSize(); + } + Point p = super.getInitialSize(); + return new Point(width, p.y); + } + public String getComment() { return commitCommentArea.getComment(); } + + public IResource[] getResourcesToCommit() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.dialogs.DetailsDialog#createDropDownDialogArea(org.eclipse.swt.widgets.Composite) + */ + protected Composite createDropDownDialogArea(Composite parent) { + try { + CompareConfiguration compareConfig = new CompareConfiguration(); + compareConfig.setLeftEditable(false); + TreeViewerAdvisor viewerAdvisor = new TreeViewerAdvisor(set); + compareEditorInput = new SynchronizeCompareInput(compareConfig, viewerAdvisor) { + public String getTitle() { + return "Resources to commit"; + } + protected StructuredViewer internalCreateDiffViewer(Composite parent, TreeViewerAdvisor diffViewerConfiguration) { + ContainerCheckedTreeViewer viewer = new TreeViewerAdvisor.NavigableCheckboxTreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + viewer.setCheckedElements(set.getResources()); + GridData data = new GridData(GridData.FILL_BOTH); + viewer.getControl().setLayoutData(data); + diffViewerConfiguration.initializeViewer(viewer); + return viewer; + } + }; + // We don't need a progress monitor because the actualy model will be built + // by the event processing thread. + compareEditorInput.run(new NullProgressMonitor()); + } catch (InterruptedException e) { + Utils.handle(e); + } catch (InvocationTargetException e) { + Utils.handle(e); + } + + Composite result= new Composite(parent, SWT.NONE); + GridLayout layout= new GridLayout(); + result.setLayout(layout); + GridData data = new GridData(GridData.FILL_BOTH); + data.grabExcessHorizontalSpace = true; + data.grabExcessVerticalSpace = true; + data.heightHint = 350; + result.setLayoutData(data); + Label l = new Label(result, SWT.WRAP); + l.setText(Policy.bind("ReleaseCommentDialog.6")); //$NON-NLS-1$ + Control c = compareEditorInput.createContents(result); + data = new GridData(GridData.FILL_BOTH); + c.setLayoutData(data); + return result; + } + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.dialogs.DetailsDialog#updateEnablements() + */ + protected void updateEnablements() { + } + + /* (non-Javadoc) + * @see org.eclipse.jface.window.Window#close() + */ + public boolean close() { + Rectangle bounds = getShell().getBounds(); + settings.put(HEIGHT_KEY, bounds.height); + settings.put(WIDTH_KEY, bounds.width); + return super.close(); + } } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/RemoteRevisionQuickDiffProvider.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/RemoteRevisionQuickDiffProvider.java index a654290c4..cc7e7d90e 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/RemoteRevisionQuickDiffProvider.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/RemoteRevisionQuickDiffProvider.java @@ -10,37 +10,23 @@ *******************************************************************************/ package org.eclipse.team.internal.ccvs.ui; -import java.io.BufferedReader; -import java.io.CharArrayWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; +import java.io.*; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.ITeamResourceChangeListener; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.core.subscribers.TeamDelta; -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.ICVSRemoteFile; +import org.eclipse.team.core.subscribers.*; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.editors.text.IStorageDocumentProvider; -import org.eclipse.ui.texteditor.IDocumentProvider; -import org.eclipse.ui.texteditor.IElementStateListener; -import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.ui.texteditor.*; import org.eclipse.ui.texteditor.quickdiff.IQuickDiffProviderImplementation; /** @@ -95,15 +81,15 @@ public class RemoteRevisionQuickDiffProvider implements IQuickDiffProviderImplem /** * Updates the document if a sync changes occurs to the associated CVS file. */ - private ITeamResourceChangeListener teamChangeListener = new ITeamResourceChangeListener() { - public void teamResourceChanged(TeamDelta[] deltas) { + private ISubscriberChangeListener teamChangeListener = new ISubscriberChangeListener() { + public void subscriberResourceChanged(ISubscriberChangeEvent[] deltas) { if(initialized()) { for (int i = 0; i < deltas.length; i++) { - TeamDelta delta = deltas[i]; + ISubscriberChangeEvent delta = deltas[i]; IResource resource = delta.getResource(); if(resource.getType() == IResource.FILE && fLastSyncState != null && resource.equals(fLastSyncState.getLocal())) { - if(delta.getFlags() == TeamDelta.SYNC_CHANGED) { + if(delta.getFlags() == ISubscriberChangeEvent.SYNC_CHANGED) { fetchContentsInJob(); } } @@ -218,7 +204,7 @@ public class RemoteRevisionQuickDiffProvider implements IQuickDiffProviderImplem private boolean computeChange(IProgressMonitor monitor) throws TeamException { boolean needToUpdateReferenceDocument = false; if(initialized()) { - SyncInfo info = getSyncState(getFileFromEditor(), monitor); + SyncInfo info = getSyncState(getFileFromEditor()); // check if if(info == null && fLastSyncState != null) { return true; @@ -236,16 +222,16 @@ public class RemoteRevisionQuickDiffProvider implements IQuickDiffProviderImplem } private void debug(SyncInfo lastSyncState, SyncInfo info) { - String last = "[none]"; + String last = "[none]"; //$NON-NLS-1$ if(lastSyncState != null) { last = lastSyncState.toString(); } - System.out.println("+ CVSQuickDiff: was " + last + " is " + info.toString()); + System.out.println("+ CVSQuickDiff: was " + last + " is " + info.toString()); //$NON-NLS-1$ //$NON-NLS-2$ } - private SyncInfo getSyncState(IResource resource, IProgressMonitor monitor) throws TeamException { + private SyncInfo getSyncState(IResource resource) throws TeamException { ICVSFile cvsFile = getManagedCVSFile(); - return CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().getSyncInfo(resource, monitor); + return CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().getSyncInfo(resource); } /** @@ -292,7 +278,7 @@ public class RemoteRevisionQuickDiffProvider implements IQuickDiffProviderImplem } else { // the remote is null, so ensure that the document is null fReference = new Document(); - fReference.set(""); + fReference.set(""); //$NON-NLS-1$ } } @@ -327,13 +313,13 @@ public class RemoteRevisionQuickDiffProvider implements IQuickDiffProviderImplem } document.set(caw.toString()); } catch (IOException x) { - throw new CVSException(Policy.bind("RemoteRevisionQuickDiffProvider.readingFile"), x); + throw new CVSException(Policy.bind("RemoteRevisionQuickDiffProvider.readingFile"), x); //$NON-NLS-1$ } finally { if (in != null) { try { in.close(); } catch (IOException x) { - throw new CVSException(Policy.bind("RemoteRevisionQuickDiffProvider.closingFile"), x); + throw new CVSException(Policy.bind("RemoteRevisionQuickDiffProvider.closingFile"), x); //$NON-NLS-1$ } } } @@ -380,7 +366,7 @@ public class RemoteRevisionQuickDiffProvider implements IQuickDiffProviderImplem } catch (InterruptedException e) { } } - Job updateJob = new Job(Policy.bind("RemoteRevisionQuickDiffProvider.fetchingFile")) { + Job updateJob = new Job(Policy.bind("RemoteRevisionQuickDiffProvider.fetchingFile")) { //$NON-NLS-1$ protected IStatus run(IProgressMonitor monitor) { try { readDocument(monitor); diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ResourceEditionNode.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ResourceEditionNode.java index 20cd55497..977288b4c 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ResourceEditionNode.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ResourceEditionNode.java @@ -15,16 +15,14 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; -import org.eclipse.compare.CompareUI; -import org.eclipse.compare.IStreamContentAccessor; -import org.eclipse.compare.ITypedElement; +import org.eclipse.compare.*; import org.eclipse.compare.structuremergeviewer.IStructureComparator; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.swt.graphics.Image; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.IRemoteResource; +import org.eclipse.team.core.synchronize.IResourceVariant; import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource; /** @@ -65,10 +63,10 @@ public class ResourceEditionNode implements IStructureComparator, ITypedElement, CVSUIPlugin.runWithProgress(null, true /*cancelable*/, new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { try { - IRemoteResource[] members = resource.members(monitor); + ICVSRemoteResource[] members = resource.members(monitor); children = new ResourceEditionNode[members.length]; for (int i = 0; i < members.length; i++) { - children[i] = new ResourceEditionNode((ICVSRemoteResource)members[i]); + children[i] = new ResourceEditionNode(members[i]); } } catch (TeamException e) { throw new InvocationTargetException(e); @@ -100,9 +98,11 @@ public class ResourceEditionNode implements IStructureComparator, ITypedElement, CVSUIPlugin.runWithProgress(null, true /*cancelable*/, new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { try { - holder[0] = resource.getContents(monitor); + holder[0] = ((IResourceVariant)resource).getStorage(monitor).getContents(); } catch (TeamException e) { throw new InvocationTargetException(e); + } catch (CoreException e) { + throw new InvocationTargetException(e); } } }); diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/TimeoutProgressMonitorDialog.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/TimeoutProgressMonitorDialog.java index 42130ae0e..8f1bb9353 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/TimeoutProgressMonitorDialog.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/TimeoutProgressMonitorDialog.java @@ -39,7 +39,7 @@ public class TimeoutProgressMonitorDialog extends ProgressMonitorDialog { } /* (non-Javadoc) - * Method declared on IRunnableContext. + * Method declared on ITeamRunnableContext. * Runs the given <code>IRunnableWithProgress</code> with the progress monitor for this * progress dialog. The dialog is opened before it is run, and closed after it completes. */ diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CVSAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CVSAction.java index 4a7e054ce..19fd01fea 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CVSAction.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CVSAction.java @@ -11,21 +11,12 @@ package org.eclipse.team.internal.ccvs.ui.actions; import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; +import java.util.*; import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.*; import org.eclipse.jface.action.IAction; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.dialogs.*; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.viewers.IStructuredSelection; @@ -33,30 +24,22 @@ import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.CVSStatus; -import org.eclipse.team.internal.ccvs.core.CVSTag; -import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder; -import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource; -import org.eclipse.team.internal.ccvs.core.ICVSResource; -import org.eclipse.team.internal.ccvs.core.ILogEntry; +import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; -import org.eclipse.team.internal.ccvs.ui.AvoidableMessageDialog; -import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; -import org.eclipse.team.internal.ccvs.ui.ICVSUIConstants; +import org.eclipse.team.internal.ccvs.ui.*; import org.eclipse.team.internal.ccvs.ui.Policy; import org.eclipse.team.internal.ccvs.ui.repo.RepositoryManager; +import org.eclipse.team.internal.ui.Utils; import org.eclipse.team.internal.ui.actions.TeamAction; import org.eclipse.team.internal.ui.dialogs.IPromptCondition; -import org.eclipse.team.internal.ui.synchronize.views.SynchronizeViewNode; -import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.*; /** * CVSAction is the common superclass for all CVS actions. It provides * facilities for enablement handling, standard error handling, selection * retrieval and prompting. */ -abstract public class CVSAction extends TeamAction { +abstract public class CVSAction extends TeamAction implements IEditorActionDelegate { private List accumulatedStatus = new ArrayList(); @@ -481,20 +464,9 @@ abstract public class CVSAction extends TeamAction { * @see org.eclipse.team.internal.ui.actions.TeamAction#getSelectedResources() */ protected IResource[] getSelectedResources() { - if(selection.isEmpty()) return new IResource[0]; - Iterator it = selection.iterator(); - List resources = new ArrayList(); - while(it.hasNext()) { - Object element = it.next(); - if(element instanceof SynchronizeViewNode) { - resources.add(((SynchronizeViewNode)element).getResource()); - } else { - Object adapter = getAdapter(element, IResource.class); - if (adapter instanceof IResource) { - resources.add(adapter); -} - } - } - return (IResource[]) resources.toArray(new IResource[resources.size()]); - } + return Utils.getResources(selection.toArray()); + } + + public void setActiveEditor(IAction action, IEditorPart targetEditor) { + } } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CompareWithTagAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CompareWithTagAction.java index b81125a8d..5acb560be 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CompareWithTagAction.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CompareWithTagAction.java @@ -12,39 +12,53 @@ package org.eclipse.team.internal.ccvs.ui.actions; import java.lang.reflect.InvocationTargetException; -import org.eclipse.compare.CompareUI; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.action.IAction; -import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.team.internal.ccvs.core.CVSCompareSubscriber; import org.eclipse.team.internal.ccvs.core.CVSTag; -import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource; -import org.eclipse.team.internal.ccvs.ui.CVSLocalCompareEditorInput; -import org.eclipse.team.internal.ccvs.ui.TagSelectionDialog; +import org.eclipse.team.internal.ccvs.ui.*; +import org.eclipse.team.internal.ccvs.ui.subscriber.CompareParticipant; +import org.eclipse.team.ui.TeamUI; +import org.eclipse.team.ui.synchronize.*; +import org.eclipse.ui.*; public class CompareWithTagAction extends WorkspaceAction { public void execute(IAction action) throws InvocationTargetException, InterruptedException { - final ICVSRemoteResource[] remoteResource = new ICVSRemoteResource[] { null }; - final IResource[] resources = getSelectedResources(); - + IResource[] resources = getSelectedResources(); + CVSTag tag = promptForTag(resources); + if (tag == null) + return; + IWorkbenchWindow wWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + IWorkbenchPage activePage = null; + if (wWindow != null) { + activePage = wWindow.getActivePage(); + } + // Create the synchronize view participant + CVSCompareSubscriber s = new CVSCompareSubscriber(resources, tag); + CompareParticipant participant = new CompareParticipant(s); + // Show the participant in the view + ISynchronizeManager manager = TeamUI.getSynchronizeManager(); + manager.addSynchronizeParticipants(new ISynchronizeParticipant[]{participant}); + ISynchronizeView view = manager.showSynchronizeViewInActivePage(null); + if (view != null) { + view.display(participant); + participant.refreshWithRemote(s.roots()); + } else { + CVSUIPlugin.openError(getShell(), Policy.bind("error"), Policy.bind("Error.unableToShowSyncView"), null); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + protected CVSTag promptForTag(IResource[] resources) { IProject[] projects = new IProject[resources.length]; for (int i = 0; i < resources.length; i++) { projects[i] = resources[i].getProject(); } - final CVSTag tag = TagSelectionDialog.getTagToCompareWith(getShell(), projects); - if (tag == null) return; - // Show the compare viewer - run(new IRunnableWithProgress() { - public void run(IProgressMonitor monitor) throws InvocationTargetException { - CompareUI.openCompareEditorOnPage( - new CVSLocalCompareEditorInput(resources, tag), - getTargetPage()); - } - }, false /* cancelable */, PROGRESS_BUSYCURSOR); + CVSTag tag = TagSelectionDialog.getTagToCompareWith(getShell(), projects); + return tag; } - + /* (non-Javadoc) * @see org.eclipse.team.internal.ccvs.ui.actions.WorkspaceAction#isEnabledForNonExistantResources() */ diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/SyncAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/SyncAction.java index 7af6fff06..1a8a7668f 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/SyncAction.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/SyncAction.java @@ -16,11 +16,7 @@ import org.eclipse.core.resources.IResource; import org.eclipse.jface.action.IAction; import org.eclipse.team.internal.ccvs.core.CVSException; import org.eclipse.team.internal.ccvs.core.ICVSResource; -import org.eclipse.team.internal.ccvs.ui.*; -import org.eclipse.team.internal.ccvs.ui.sync.CVSSyncCompareInput; -import org.eclipse.team.internal.ui.sync.SyncCompareInput; -import org.eclipse.team.internal.ui.sync.SyncView; -import org.eclipse.ui.IWorkingSet; +import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; /** * Action for catchup/release in popup menus. @@ -31,27 +27,7 @@ public class SyncAction extends WorkspaceAction { IResource[] resources = getResourcesToSync(); if (resources == null || resources.length == 0) return; - IWorkingSet workingSet = CVSUIPlugin.getWorkingSet(resources, Policy.bind("SyncAction.workingSetName")); //$NON-NLS-1$ - CVSUIPlugin.showInSyncView(getShell(), resources, workingSet, 0 /* no mode in particular */); - } - - public void executeInOldSyncView(IAction action) throws InvocationTargetException { - try { - IResource[] resources = getResourcesToSync(); - if (resources == null || resources.length == 0) return; - SyncCompareInput input = getCompareInput(resources); - if (input == null) return; - SyncView view = SyncView.findViewInActivePage(getTargetPage()); - if (view != null) { - view.showSync(input, getTargetPage()); - } - } catch (CVSException e) { - throw new InvocationTargetException(e); - } - } - - protected SyncCompareInput getCompareInput(IResource[] resources) throws CVSException { - return new CVSSyncCompareInput(resources); + CVSUIPlugin.showInSyncView(getShell(), resources, 0 /* no mode in particular */); } protected IResource[] getResourcesToSync() { diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties index 5291e1fe4..af2b1022e 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties @@ -1042,13 +1042,13 @@ RemoteRevisionQuickDiffProvider.closingFile=Error closing remote file RemoteRevisionQuickDiffProvider.fetchingFile=CVS QuickDiff: fetching remote contents for ''{0}'' RemoteCompareOperation.0=Comparing tags {0} and {1} of {2} action.SynchronizeViewCommit.label=Commit -action.SynchronizeViewCommit.tooltip=Commit All Outgoing Changes -action.SynchronizeViewCommit.description=Commit All Outgoing Changes +action.SynchronizeViewCommit.tooltip=Commit All Outgoing Changes... +action.SynchronizeViewCommit.description=Commit All Outgoing Changes... action.SynchronizeViewCommit.image=checkin_action.gif action.SynchronizeViewUpdate.label=Update -action.SynchronizeViewUpdate.tooltip=Update All Incoming Changes -action.SynchronizeViewUpdate.description=Update All Incoming Changes +action.SynchronizeViewUpdate.tooltip=Update All Incoming Changes... +action.SynchronizeViewUpdate.description=Update All Incoming Changes... action.SynchronizeViewUpdate.image=checkout_action.gif MergeSynchronizeParticipant.8=Missing id initializing cvs merge participant @@ -1060,5 +1060,14 @@ DisconnectOperation.0=Disconnecting SubscriberConfirmMergedAction.0=Synchronization information is missing for resource {0} SubscriberConfirmMergedAction.jobName=Performing a CVS Mark as Merged operation on {0} resources. CVSSubscriberAction.0=Invalid attemp to make unsupervised resource {0} in-sync. +ReleaseCommentDialog.6=Review resources that will be committed: +ReconcileProjectOperation.0=Reconciling project {0} with remote folder {1} +CheckoutToRemoteFolderOperation.0=Downloading folder {0} +CVSRepositoryPropertiesPage.21=Use this location's connection information for all connections +CVSRepositoryPropertiesPage.22=Use the following locations for read and write access +CVSRepositoryPropertiesPage.23=Read: +CVSRepositoryPropertiesPage.24=Write: +CompareRevertAction.0=Reverting {0} resources FileModificationValidator.3=Perform Edit? FileModificationValidator.4=A CVS edit notification is required to be sent to the server in order to allow editing of one or more selected files. Continue? +CVSSynchronizeViewPage.0=Show incoming grouped by comment diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/CVSModelElement.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/CVSModelElement.java index 5fb8cfb18..f7f7e0966 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/CVSModelElement.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/CVSModelElement.java @@ -46,7 +46,7 @@ public abstract class CVSModelElement implements IWorkbenchAdapter, IAdaptable { /** * Returns the runnableContext. - * @return IRunnableContext + * @return ITeamRunnableContext */ public IRunnableContext getRunnableContext() { if (runnableContext == null) { diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/CVSRootFolderElement.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/CVSRootFolderElement.java index 285823da8..f7c9d497d 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/CVSRootFolderElement.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/CVSRootFolderElement.java @@ -24,7 +24,7 @@ public class CVSRootFolderElement extends CVSResourceElement { } /** - * @see IWorkbenchAdapter#getChildren(Object) + * @see IWorkbenchAdapter#members(Object) */ public Object[] fetchChildren(Object o, IProgressMonitor monitor) { CVSFolderElement[] folders = new CVSFolderElement[roots.length]; diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSOperation.java index 476b4afab..b4a480786 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSOperation.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSOperation.java @@ -24,6 +24,7 @@ import org.eclipse.team.internal.ccvs.core.CVSStatus; import org.eclipse.team.internal.ccvs.core.util.Assert; import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; import org.eclipse.team.internal.ccvs.ui.Policy; +import org.eclipse.team.internal.ui.actions.*; /** @@ -46,7 +47,7 @@ public abstract class CVSOperation implements IRunnableWithProgress { // instance variable used to indicate behavior while prompting for overwrite private boolean confirmOverwrite = true; - ICVSRunnableContext cvsRunnableContext; + ITeamRunnableContext cvsRunnableContext; public CVSOperation(Shell shell) { this.shell = shell; @@ -146,14 +147,14 @@ public abstract class CVSOperation implements IRunnableWithProgress { protected abstract void execute(IProgressMonitor monitor) throws CVSException, InterruptedException; /* - * Return the ICVSRunnableContext which will be used to run the operation. + * Return the ITeamRunnableContext which will be used to run the operation. */ - private ICVSRunnableContext getCVSRunnableContext() { + private ITeamRunnableContext getCVSRunnableContext() { if (cvsRunnableContext == null) { if (canRunAsJob() && areJobsEnabled()) { - return new CVSNonblockingRunnableContext(); + return new JobRunnableContext(); } else { - return new CVSBlockingRunnableContext(shell); + return new ProgressDialogRunnableContext(shell); } } return cvsRunnableContext; @@ -166,7 +167,7 @@ public abstract class CVSOperation implements IRunnableWithProgress { * for testing purposes. * @param cvsRunnableContext */ - public void setCVSRunnableContext(ICVSRunnableContext cvsRunnableContext) { + public void setCVSRunnableContext(ITeamRunnableContext cvsRunnableContext) { this.cvsRunnableContext = cvsRunnableContext; } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSSubscriberNonblockingContext.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSSubscriberNonblockingContext.java deleted file mode 100644 index c880bcd84..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSSubscriberNonblockingContext.java +++ /dev/null @@ -1,30 +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.ui.operations; - -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.team.internal.ui.jobs.JobStatusHandler; -import org.eclipse.team.ui.synchronize.actions.SubscriberAction; - -/** - * This context uses the JobStatusHandler from SubscriberAction to ensure - * proper busy indication in the sync view. - */ -public class CVSSubscriberNonblockingContext extends CVSNonblockingRunnableContext { - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ccvs.ui.operations.CVSNonblockingRunnableContext#schedule(org.eclipse.core.runtime.jobs.Job) - */ - protected void schedule(Job job) { - JobStatusHandler.schedule(job, SubscriberAction.SUBSCRIBER_JOB_TYPE); - } - -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutToRemoteFolderOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutToRemoteFolderOperation.java index 4d60a1596..342ef48d0 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutToRemoteFolderOperation.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutToRemoteFolderOperation.java @@ -172,7 +172,7 @@ public class CheckoutToRemoteFolderOperation extends CheckoutOperation { * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#getTaskName() */ protected String getTaskName() { - return "Downloading folder {0}" + getRemoteFolders()[0].getName(); + return Policy.bind("CheckoutToRemoteFolderOperation.0", getRemoteFolders()[0].getName()); //$NON-NLS-1$ } protected IStatus checkout(final ICVSRemoteFolder resource, final ICVSFolder sandbox, IProgressMonitor pm) throws CVSException { diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/FetchMembersOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/FetchMembersOperation.java index 8f3de3dac..8dabc8a7e 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/FetchMembersOperation.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/FetchMembersOperation.java @@ -18,12 +18,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.progress.IElementCollector; import org.eclipse.swt.widgets.Shell; 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.ICVSFile; -import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder; -import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource; +import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.core.resources.RemoteFolder; import org.eclipse.team.internal.ccvs.core.resources.RemoteFolderMemberFetcher; import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; @@ -120,7 +115,7 @@ public class FetchMembersOperation extends RemoteOperation { monitor = Policy.monitorFor(monitor); try { monitor.beginTask(null, 100); - IRemoteResource[] children = remote.members(Policy.subMonitorFor(monitor, 95)); + ICVSRemoteResource[] children = remote.members(Policy.subMonitorFor(monitor, 95)); collector.add(children, Policy.subMonitorFor(monitor, 5)); } catch (TeamException e) { throw CVSException.wrapException(e); diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ReconcileProjectOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ReconcileProjectOperation.java index 550733383..376208d7a 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ReconcileProjectOperation.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ReconcileProjectOperation.java @@ -16,15 +16,9 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; -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.ICVSRemoteFolder; -import org.eclipse.team.internal.ccvs.core.ICVSRunnable; -import org.eclipse.team.internal.ccvs.core.resources.CVSRemoteSyncElement; -import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; +import org.eclipse.team.core.synchronize.IResourceVariant; +import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; import org.eclipse.team.internal.ccvs.ui.Policy; @@ -50,11 +44,11 @@ public class ReconcileProjectOperation extends CVSOperation { monitor.beginTask(null, 300); ICVSRemoteFolder remote = CheckoutToRemoteFolderOperation.checkoutRemoteFolder(getShell(), folder, Policy.subMonitorFor(monitor, 100)); // TODO: make -in-sync should also be done by the subscriber - makeFoldersInSync(project, remote, Policy.subMonitorFor(monitor, 100)); - CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().setRemote(project, remote,Policy.subMonitorFor(monitor, 100)); +// makeFoldersInSync(project, remote, Policy.subMonitorFor(monitor, 100)); + CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().setRemote(project, (IResourceVariant)remote, Policy.subMonitorFor(monitor, 100)); Display.getDefault().asyncExec(new Runnable() { public void run() { - CVSUIPlugin.showInSyncView(getShell(), null, null, 0 /* no mode in particular */); + CVSUIPlugin.showInSyncView(getShell(), null, 0 /* no mode in particular */); } }); } catch (InvocationTargetException e) { @@ -67,31 +61,30 @@ public class ReconcileProjectOperation extends CVSOperation { } - /** - * Sync the given unshared project with the given repository and module. - */ - public IRemoteSyncElement makeFoldersInSync(final IProject project, ICVSRemoteFolder remote, IProgressMonitor progress) throws TeamException { - final CVSRemoteSyncElement tree = new CVSRemoteSyncElement(true /*three way*/, project, null, remote); - CVSWorkspaceRoot.getCVSFolderFor(project).run(new ICVSRunnable() { - public void run(IProgressMonitor monitor) throws CVSException { - monitor.beginTask(null, 100); - try { - tree.makeFoldersInSync(Policy.subMonitorFor(monitor, 100)); - RepositoryProvider.map(project, CVSProviderPlugin.getTypeId()); - } catch (TeamException e) { - throw CVSException.wrapException(e); - } - monitor.done(); - } - }, progress); - return tree; - } +// /** +// * Sync the given unshared project with the given repository and module. +// */ +// public void makeFoldersInSync(final IProject project, ICVSRemoteFolder remote, IProgressMonitor progress) throws TeamException { +// final CVSRemoteSyncElement tree = new CVSRemoteSyncElement(true /*three way*/, project, null, remote); +// CVSWorkspaceRoot.getCVSFolderFor(project).run(new ICVSRunnable() { +// public void run(IProgressMonitor monitor) throws CVSException { +// monitor.beginTask(null, 100); +// try { +// tree.makeFoldersInSync(Policy.subMonitorFor(monitor, 100)); +// RepositoryProvider.map(project, CVSProviderPlugin.getTypeId()); +// } catch (TeamException e) { +// throw CVSException.wrapException(e); +// } +// monitor.done(); +// } +// }, progress); +// } /* (non-Javadoc) * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#getTaskName() */ protected String getTaskName() { - return "Reconciling project {0} with remote folder {1}" + project.getName() + folder.getRepositoryRelativePath(); + return Policy.bind("ReconcileProjectOperation.0", project.getName(), folder.getRepositoryRelativePath()); //$NON-NLS-1$ } } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/CVSRepositoryPropertiesPage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/CVSRepositoryPropertiesPage.java index 12d3dc4c3..4f46d0bcd 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/CVSRepositoryPropertiesPage.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/CVSRepositoryPropertiesPage.java @@ -181,11 +181,11 @@ public class CVSRepositoryPropertiesPage extends PropertyPage { */ private void createReadWriteAccessComposite(Composite composite) { Composite radioGroup = createRadioGroupComposite(composite); - useDefaultReadWriteLocations = createRadioButton(radioGroup, "Use this location's connection information for all connections", 3); - useCustomReadWriteLocations = createRadioButton(radioGroup, "Use the following locations for read and write access", 3); - createLabel(composite, "Read:", 1); + useDefaultReadWriteLocations = createRadioButton(radioGroup, Policy.bind("CVSRepositoryPropertiesPage.21"), 3); //$NON-NLS-1$ + useCustomReadWriteLocations = createRadioButton(radioGroup, Policy.bind("CVSRepositoryPropertiesPage.22"), 3); //$NON-NLS-1$ + createLabel(composite, Policy.bind("CVSRepositoryPropertiesPage.23"), 1); //$NON-NLS-1$ readLocation = createCombo(composite); - createLabel(composite, "Write:", 1); + createLabel(composite, Policy.bind("CVSRepositoryPropertiesPage.24"), 1); //$NON-NLS-1$ writeLocation = createCombo(composite); } /** diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RemoveRootAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RemoveRootAction.java index 7b93fbb2c..7b22b5605 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RemoveRootAction.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RemoveRootAction.java @@ -14,10 +14,10 @@ import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Iterator; -import org.eclipse.core.internal.jobs.JobManager; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.IStructuredSelection; @@ -118,13 +118,13 @@ public class RemoveRootAction extends SelectionListenerAction { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { ISchedulingRule rule = new RepositoryLocationSchedulingRule(root); try { - JobManager.getInstance().beginRule(rule, monitor); + Platform.getJobManager().beginRule(rule, monitor); view.getContentProvider().cancelJobs(root); provider.disposeRepository(root); } catch (CVSException e) { throw new InvocationTargetException(e); } finally { - JobManager.getInstance().endRule(rule); + Platform.getJobManager().endRule(rule); } } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryManager.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryManager.java index 91b93453c..900540608 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryManager.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryManager.java @@ -11,61 +11,25 @@ package org.eclipse.team.internal.ccvs.ui.repo; -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.DataInputStream; -import java.io.EOFException; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; +import javax.xml.parsers.*; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.core.runtime.*; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.swt.widgets.Shell; 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.CVSTag; -import org.eclipse.team.internal.ccvs.core.CVSTeamProvider; -import org.eclipse.team.internal.ccvs.core.ICVSFolder; -import org.eclipse.team.internal.ccvs.core.ICVSListener; -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.*; import org.eclipse.team.internal.ccvs.core.client.Command; import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation; -import org.eclipse.team.internal.ccvs.ui.AddToVersionControlDialog; -import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; -import org.eclipse.team.internal.ccvs.ui.IRepositoryListener; +import org.eclipse.team.internal.ccvs.ui.*; import org.eclipse.team.internal.ccvs.ui.Policy; -import org.eclipse.team.internal.ccvs.ui.ReleaseCommentDialog; -import org.eclipse.team.internal.ccvs.ui.XMLWriter; import org.eclipse.ui.IWorkingSet; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -615,27 +579,11 @@ public class RepositoryManager { } /** - * Mark the files as merged. - */ - public void merged(IRemoteSyncElement[] elements) throws TeamException { - Map table = getProviderMapping(elements); - Set keySet = table.keySet(); - Iterator iterator = keySet.iterator(); - while (iterator.hasNext()) { - CVSTeamProvider provider = (CVSTeamProvider)iterator.next(); - provider.setComment(getCurrentComment()); - List list = (List)table.get(provider); - IRemoteSyncElement[] providerElements = (IRemoteSyncElement[])list.toArray(new IRemoteSyncElement[list.size()]); - provider.merged(providerElements); - } - } - - /** * Return the entered comment or null if canceled. */ public String promptForComment(final Shell shell, IResource[] resourcesToCommit) { final int[] result = new int[1]; - final ReleaseCommentDialog dialog = new ReleaseCommentDialog(shell, resourcesToCommit); + final ReleaseCommentDialog dialog = new ReleaseCommentDialog(shell, resourcesToCommit, IResource.DEPTH_INFINITE); shell.getDisplay().syncExec(new Runnable() { public void run() { result[0] = dialog.open(); @@ -712,23 +660,6 @@ public class RepositoryManager { } return result; } - /** - * Helper method. Return a Map mapping provider to a list of IRemoteSyncElements - * shared with that provider. - */ - private Map getProviderMapping(IRemoteSyncElement[] elements) { - Map result = new HashMap(); - for (int i = 0; i < elements.length; i++) { - RepositoryProvider provider = RepositoryProvider.getProvider(elements[i].getLocal().getProject(), CVSProviderPlugin.getTypeId()); - List list = (List)result.get(provider); - if (list == null) { - list = new ArrayList(); - result.put(provider, list); - } - list.add(elements[i]); - } - return result; - } public ICVSRepositoryLocation getRepositoryLocationFor(ICVSResource resource) { try { diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSLocalCompareConfiguration.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSLocalCompareConfiguration.java new file mode 100644 index 000000000..feee7f4bd --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSLocalCompareConfiguration.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * 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.ui.subscriber; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.action.*; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.core.subscribers.SubscriberSyncInfoCollector; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.internal.ccvs.core.*; +import org.eclipse.team.ui.synchronize.subscriber.RefreshAction; +import org.eclipse.team.ui.synchronize.viewers.TreeViewerAdvisor; + +/** + * Provides compare specific support + */ +public class CVSLocalCompareConfiguration extends TreeViewerAdvisor { + + private CVSCompareSubscriber subscriber; + private SubscriberSyncInfoCollector collector; + private RefreshAction refreshAction; + private RefreshAction refreshAllAction; + + /** + * Return a <code>SyncInfoSetCompareConfiguration</code> that can be used in a + * <code>SynchronizeCompareInput</code> to show the comparsion between the local + * workspace resources and their tagged counterparts on the server. + * @param resources the resources to be compared + * @param tag the tag to be compared with + * @return a configuration for a <code>SynchronizeCompareInput</code> + */ + public static CVSLocalCompareConfiguration create(IResource[] resources, CVSTag tag) { + CVSCompareSubscriber subscriber = new CVSCompareSubscriber(resources, tag); + SubscriberSyncInfoCollector collector = new SubscriberSyncInfoCollector(subscriber); + collector.setFilter(new SyncInfoFilter() { + private SyncInfoFilter contentCompare = new SyncInfoFilter.ContentComparisonSyncInfoFilter(); + public boolean select(SyncInfo info, IProgressMonitor monitor) { + if (info.getLocal().getType() == IResource.FILE) { + // Want to select infos whose contents do not match + return !contentCompare.select(info, monitor); + } else { + return true; + } + } + }); + collector.start(); + return new CVSLocalCompareConfiguration(subscriber, collector); + } + + private CVSLocalCompareConfiguration(CVSCompareSubscriber subscriber, SubscriberSyncInfoCollector collector) { + super("org.eclipse.team.cvs.ui.compare-participant", collector.getSyncInfoTree()); //$NON-NLS-1$ + this.subscriber = subscriber; + this.collector = collector; + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SyncInfoSetCompareConfiguration#dispose() + */ + public void dispose() { + collector.dispose(); + subscriber.dispose(); + super.dispose(); + } + + public Object prepareInput(IProgressMonitor monitor) throws TeamException { + subscriber.refresh(subscriber.roots(), IResource.DEPTH_INFINITE, monitor); + collector.waitForCollector(monitor); + return super.prepareInput(monitor); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SyncInfoSetCompareConfiguration#fillContextMenu(org.eclipse.jface.viewers.StructuredViewer, org.eclipse.jface.action.IMenuManager) + */ + protected void fillContextMenu(StructuredViewer viewer, IMenuManager manager) { + manager.add(refreshAction); + manager.add(new Separator()); + super.fillContextMenu(viewer, manager); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.TreeViewerAdvisor#contributeToToolBar(org.eclipse.jface.action.IToolBarManager) + */ + public void contributeToToolBar(IToolBarManager tbm) { + tbm.add(refreshAllAction); + } + + protected void initializeActions(StructuredViewer viewer) { + super.initializeActions(viewer); + refreshAction = new RefreshAction(viewer, ((CVSSyncTreeSubscriber)collector.getSubscriber()).getName(), collector, null /* no listener */, false); + refreshAllAction = new RefreshAction(viewer, ((CVSSyncTreeSubscriber)collector.getSubscriber()).getName(), collector, null /* no listener */, true); + } + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SyncInfoSetCompareConfiguration#getSyncSet() + */ + public SyncInfoTree getSyncInfoTree() { + return collector.getSyncInfoTree(); + } +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSSubscriberAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSSubscriberAction.java index 6a361f3bb..24e58168c 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSSubscriberAction.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSSubscriberAction.java @@ -11,27 +11,23 @@ package org.eclipse.team.internal.ccvs.ui.subscriber; import java.lang.reflect.InvocationTargetException; -import java.util.*; +import java.util.ArrayList; +import java.util.List; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.*; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.eclipse.core.runtime.jobs.MultiRule; -import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; +import org.eclipse.team.core.synchronize.*; import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.core.client.PruneFolderVisitor; import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer; import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; import org.eclipse.team.internal.ccvs.ui.Policy; -import org.eclipse.team.internal.ccvs.ui.operations.*; import org.eclipse.team.internal.ui.TeamUIPlugin; -import org.eclipse.team.ui.synchronize.actions.SubscriberAction; -import org.eclipse.team.ui.synchronize.actions.SyncInfoSet; +import org.eclipse.team.internal.ui.actions.SubscriberAction; public abstract class CVSSubscriberAction extends SubscriberAction { @@ -126,7 +122,7 @@ public abstract class CVSSubscriberAction extends SubscriberAction { * Sync actions seem to need to be sync-execed to work * @param t */ - protected void handle(Throwable t) { + protected void handle(Exception t) { CVSUIPlugin.openError(getShell(), getErrorTitle(), null, t, CVSUIPlugin.PERFORM_SYNC_EXEC | CVSUIPlugin.LOG_NONTEAM_EXCEPTIONS); } @@ -137,25 +133,6 @@ public abstract class CVSSubscriberAction extends SubscriberAction { protected String getErrorTitle() { return null; } - - /* (non-Javadoc) - * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) - */ - public void run(IAction action) { -// TODO: Saving can change the sync state! How should this be handled? -// boolean result = saveIfNecessary(); -// if (!result) return null; - - SyncInfoSet syncSet = getFilteredSyncInfoSet(getFilteredSyncInfos()); - if (syncSet == null || syncSet.isEmpty()) return; - try { - getCVSRunnableContext().run(getJobName(syncSet), getSchedulingRule(syncSet), true, getRunnable(syncSet)); - } catch (InvocationTargetException e) { - handle(e); - } catch (InterruptedException e) { - // nothing to do; - } - } /** * Return an IRunnableWithProgress that will operate on the given sync set. @@ -189,65 +166,9 @@ public abstract class CVSSubscriberAction extends SubscriberAction { }; } - protected abstract void run(SyncInfoSet syncSet, IProgressMonitor monitor) throws TeamException; - - /* - * Return the ICVSRunnableContext which will be used to run the operation. - */ - private ICVSRunnableContext getCVSRunnableContext() { - if (canRunAsJob() && areJobsEnabled()) { - return new CVSSubscriberNonblockingContext(); - } else { - return new CVSBlockingRunnableContext(shell); - } - } - - protected boolean areJobsEnabled() { - return true; - } - - /** - * Return the job name to be used if the action can run as a job. - * - * @param syncSet - * @return - */ - protected abstract String getJobName(SyncInfoSet syncSet); - - /** - * Return a scheduling rule that includes all resources that will be operated - * on by the subscriber action. The default behavior is to include all projects - * effected by the operation. Subclasses may override. - * - * @param syncSet - * @return - */ - protected ISchedulingRule getSchedulingRule(SyncInfoSet syncSet) { - IResource[] resources = syncSet.getResources(); - Set set = new HashSet(); - for (int i = 0; i < resources.length; i++) { - IResource resource = resources[i]; - set.add(resource.getProject()); - } - IProject[] projects = (IProject[]) set.toArray(new IProject[set.size()]); - if (projects.length == 1) { - return projects[0]; - } else { - return new MultiRule(projects); - } - } - protected boolean canRunAsJob() { return true; } - - /** - * Filter the sync resource set using action specific criteria or input from the user. - */ - protected SyncInfoSet getFilteredSyncInfoSet(SyncInfo[] selectedResources) { - // If there are conflicts or outgoing changes in the syncSet, we need to warn the user. - return new SyncInfoSet(selectedResources); - } protected void pruneEmptyParents(SyncInfo[] nodes) throws CVSException { // TODO: A more explicit tie in to the pruning mechanism would be prefereable. @@ -270,7 +191,7 @@ public abstract class CVSSubscriberAction extends SubscriberAction { } protected SyncInfo getParent(SyncInfo info) throws TeamException { - return info.getSubscriber().getSyncInfo(info.getLocal().getParent(), new NullProgressMonitor()); + return ((CVSSyncInfo)info).getSubscriber().getSyncInfo(info.getLocal().getParent()); } protected IResource[] getIResourcesFrom(SyncInfo[] nodes) { @@ -297,4 +218,67 @@ public abstract class CVSSubscriberAction extends SubscriberAction { }); return (result[0] == UpdateDialog.YES); } + + /** + * Make the contents of the local resource match that of the remote + * without modifying the sync info of the local resource. + * If called on a new folder, the sync info will be copied. + */ + protected void makeRemoteLocal(SyncInfo info, IProgressMonitor monitor) throws TeamException { + IResourceVariant remote = info.getRemote(); + IResource local = info.getLocal(); + try { + if(remote==null) { + if (local.exists()) { + local.delete(IResource.KEEP_HISTORY, monitor); + } + } else { + if(remote.isContainer()) { + ensureContainerExists(info); + } else { + monitor.beginTask(null, 200); + try { + IFile localFile = (IFile)local; + if(local.exists()) { + localFile.setContents(remote.getStorage(Policy.subMonitorFor(monitor, 100)).getContents(), false /*don't force*/, true /*keep history*/, Policy.subMonitorFor(monitor, 100)); + } else { + ensureContainerExists(getParent(info)); + localFile.create(remote.getStorage(Policy.subMonitorFor(monitor, 100)).getContents(), false /*don't force*/, Policy.subMonitorFor(monitor, 100)); + } + } finally { + monitor.done(); + } + } + } + } catch(CoreException e) { + throw new CVSException(Policy.bind("UpdateMergeActionProblems_merging_remote_resources_into_workspace_1"), e); //$NON-NLS-1$ + } + } + + private boolean ensureContainerExists(SyncInfo info) throws TeamException { + IResource local = info.getLocal(); + // make sure that the parent exists + if (!local.exists()) { + if (!ensureContainerExists(getParent(info))) { + return false; + } + } + // make sure that the folder sync info is set; + if (isOutOfSync(info)) { + if (info instanceof CVSSyncInfo) { + CVSSyncInfo cvsInfo = (CVSSyncInfo)info; + IStatus status = cvsInfo.makeInSync(); + if (status.getSeverity() == IStatus.ERROR) { + logError(status); + return false; + } + } + } + // create the folder if it doesn't exist + ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor((IContainer)local); + if (!cvsFolder.exists()) { + cvsFolder.mkdir(); + } + return true; + } } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSSynchronizeViewCompareConfiguration.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSSynchronizeViewCompareConfiguration.java new file mode 100644 index 000000000..2a26c00c0 --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSSynchronizeViewCompareConfiguration.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * 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.ui.subscriber; + +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.*; +import org.eclipse.swt.graphics.Image; +import org.eclipse.team.internal.ccvs.ui.CVSLightweightDecorator; +import org.eclipse.team.ui.synchronize.ISynchronizeView; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberPageDiffTreeViewerConfiguration; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; +import org.eclipse.team.ui.synchronize.viewers.SyncInfoModelElement; +import org.eclipse.team.ui.synchronize.viewers.SynchronizeModelElementLabelProvider; + +public class CVSSynchronizeViewCompareConfiguration extends SubscriberPageDiffTreeViewerConfiguration { + + private boolean isGroupIncomingByComment = false; + + private static class CVSLabelDecorator extends LabelProvider implements ILabelDecorator { + public String decorateText(String input, Object element) { + String text = input; + if (element instanceof SyncInfoModelElement) { + IResource resource = ((SyncInfoModelElement)element).getResource(); + if(resource != null && resource.getType() != IResource.ROOT) { + CVSLightweightDecorator.Decoration decoration = new CVSLightweightDecorator.Decoration(); + CVSLightweightDecorator.decorateTextLabel(resource, decoration, false, true); + StringBuffer output = new StringBuffer(25); + if(decoration.prefix != null) { + output.append(decoration.prefix); + } + output.append(text); + if(decoration.suffix != null) { + output.append(decoration.suffix); + } + return output.toString(); + } + } + return text; + } + public Image decorateImage(Image base, Object element) { + return base; + } + } + + public CVSSynchronizeViewCompareConfiguration(ISynchronizeView view, SubscriberParticipant participant) { + super(view, participant); + participant.addPropertyChangeListener(this); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.TreeViewerAdvisor#getLabelProvider() + */ + protected ILabelProvider getLabelProvider() { + return new SynchronizeModelElementLabelProvider.DecoratingColorLabelProvider(new SynchronizeModelElementLabelProvider(), new CVSLabelDecorator()); + } + + public boolean isGroupIncomingByComment() { + return isGroupIncomingByComment; + } + + public void setGroupIncomingByComment(boolean enabled) { + this.isGroupIncomingByComment = enabled; + if(getParticipant().getMode() == SubscriberParticipant.INCOMING_MODE) { + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.TreeViewerAdvisor#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) + */ + public void propertyChange(PropertyChangeEvent event) { + String property = event.getProperty(); + if(property.equals(SubscriberParticipant.P_SYNCVIEWPAGE_MODE) && isGroupIncomingByComment()) { + int oldMode = ((Integer)event.getOldValue()).intValue(); + int newMode = ((Integer)event.getNewValue()).intValue(); + if(newMode == SubscriberParticipant.INCOMING_MODE || + oldMode == SubscriberParticipant.INCOMING_MODE) { + aSyncExec(new Runnable() { + public void run() { + } + }); + } + } + super.propertyChange(event); + } +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSSynchronizeViewPage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSSynchronizeViewPage.java index b8bc59c7d..46f72e43f 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSSynchronizeViewPage.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSSynchronizeViewPage.java @@ -12,35 +12,46 @@ package org.eclipse.team.internal.ccvs.ui.subscriber; import java.util.*; -import org.eclipse.core.resources.IResource; -import org.eclipse.jface.action.Action; +import org.eclipse.compare.structuremergeviewer.DiffNode; +import org.eclipse.jface.action.*; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.*; import org.eclipse.swt.widgets.Composite; -import org.eclipse.team.internal.ccvs.ui.CVSLightweightDecorator; +import org.eclipse.team.core.synchronize.SyncInfoTree; import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; -import org.eclipse.team.internal.ui.synchronize.sets.*; -import org.eclipse.team.ui.synchronize.*; -import org.eclipse.ui.IActionDelegate; - -public class CVSSynchronizeViewPage extends TeamSubscriberParticipantPage implements ISyncSetChangedListener { +import org.eclipse.team.ui.synchronize.ISynchronizeView; +import org.eclipse.team.ui.synchronize.subscriber.*; +import org.eclipse.team.ui.synchronize.viewers.ISynchronizeModelChangeListener; +import org.eclipse.team.ui.synchronize.viewers.SynchronizeModelElement; +import org.eclipse.ui.*; +import org.eclipse.team.internal.ccvs.ui.Policy; +public class CVSSynchronizeViewPage extends SubscriberParticipantPage implements ISynchronizeModelChangeListener { + private List delegates = new ArrayList(2); + private CVSSynchronizeViewCompareConfiguration config; + private Action groupByComment; protected class CVSActionDelegate extends Action { private IActionDelegate delegate; public CVSActionDelegate(IActionDelegate delegate) { this.delegate = delegate; + // Associate delegate with the synchronize view, this will allow + if(delegate instanceof IViewActionDelegate) { + ((IViewActionDelegate)delegate).init(getSynchronizeView()); + } addDelegate(this); } public void run() { - IStructuredContentProvider cp = (IStructuredContentProvider) getViewer().getContentProvider(); - StructuredSelection selection = new StructuredSelection(cp.getElements(getInput())); - if (!selection.isEmpty()) { - delegate.selectionChanged(this, selection); - delegate.run(this); + StructuredViewer viewer = (StructuredViewer)getViewer(); + if (viewer != null) { + ISelection selection = new StructuredSelection(viewer.getInput()); + if (!selection.isEmpty()) { + delegate.selectionChanged(this, selection); + delegate.run(this); + } } } @@ -49,8 +60,14 @@ public class CVSSynchronizeViewPage extends TeamSubscriberParticipantPage implem } } - public CVSSynchronizeViewPage(TeamSubscriberParticipant page, ISynchronizeView view, SubscriberInput input) { - super(page, view, input); + public CVSSynchronizeViewPage(SubscriberParticipant participant, ISynchronizeView view) { + super(participant, view); + groupByComment = new Action(Policy.bind("CVSSynchronizeViewPage.0"), Action.AS_CHECK_BOX) { //$NON-NLS-1$ + public void run() { + config.setGroupIncomingByComment(!config.isGroupIncomingByComment()); + setChecked(config.isGroupIncomingByComment()); + } + }; } /* @@ -60,24 +77,27 @@ public class CVSSynchronizeViewPage extends TeamSubscriberParticipantPage implem */ public void dispose() { super.dispose(); - getInput().getFilteredSyncSet().removeSyncSetChangedListener(this); + getViewerConfiguration().removeInputChangedListener(this); CVSUIPlugin.removePropertyChangeListener(this); } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SubscriberParticipantPage#setActionBars(org.eclipse.ui.IActionBars) + */ + public void setActionBars(IActionBars actionBars) { + super.setActionBars(actionBars); + IMenuManager mgr = actionBars.getMenuManager(); + mgr.add(new Separator()); + } /* - * (non-Javadoc) - * - * @see org.eclipse.team.internal.ui.sync.sets.ISyncSetChangedListener#syncSetChanged(org.eclipse.team.internal.ui.sync.sets.SyncSetChangedEvent) + * Update the enablement of any action delegates */ - public void syncSetChanged(SyncSetChangedEvent event) { - StructuredViewer viewer = getViewer(); - if (viewer != null && getInput() != null) { - IStructuredContentProvider cp = (IStructuredContentProvider) viewer.getContentProvider(); - StructuredSelection selection = new StructuredSelection(cp.getElements(getInput())); - for (Iterator it = delegates.iterator(); it.hasNext(); ) { - CVSActionDelegate delegate = (CVSActionDelegate) it.next(); - delegate.getDelegate().selectionChanged(delegate, selection); - } + private void updateActionEnablement(DiffNode input) { + ISelection selection = new StructuredSelection(input); + for (Iterator it = delegates.iterator(); it.hasNext(); ) { + CVSActionDelegate delegate = (CVSActionDelegate) it.next(); + delegate.getDelegate().selectionChanged(delegate, selection); } } @@ -85,41 +105,14 @@ public class CVSSynchronizeViewPage extends TeamSubscriberParticipantPage implem delegates.add(delagate); } - /* - * (non-Javadoc) - * - * @see org.eclipse.team.ui.synchronize.TeamSubscriberParticipantPage#getLabelProvider() - */ - protected ILabelProvider getLabelProvider() { - return new TeamSubscriberParticipantLabelProvider() { - protected String decorateText(String input, Object resource) { - if (resource instanceof IResource) { - CVSLightweightDecorator.Decoration decoration = new CVSLightweightDecorator.Decoration(); - CVSLightweightDecorator.decorateTextLabel((IResource) resource, decoration, false, true); - StringBuffer output = new StringBuffer(25); - if(decoration.prefix != null) { - output.append(decoration.prefix); - } - output.append(input); - if(decoration.suffix != null) { - output.append(decoration.suffix); - } - return output.toString(); - } else { - return input; - } - } - }; - } - /* (non-Javadoc) * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) */ public void propertyChange(PropertyChangeEvent event) { super.propertyChange(event); String prop = event.getProperty(); - if(prop.equals(CVSUIPlugin.P_DECORATORS_CHANGED) && getViewer() != null && getInput() != null) { - getViewer().refresh(true /* update labels */); + if(prop.equals(CVSUIPlugin.P_DECORATORS_CHANGED) && getViewer() != null && getSyncInfoSet() != null) { + ((StructuredViewer)getViewer()).refresh(true /* update labels */); } } @@ -128,7 +121,32 @@ public class CVSSynchronizeViewPage extends TeamSubscriberParticipantPage implem */ public void createControl(Composite parent) { super.createControl(parent); - getInput().getFilteredSyncSet().addSyncSetChangedListener(this); - CVSUIPlugin.addPropertyChangeListener(this); + + // Sync changes are used to update the action state for the update/commit buttons. + getViewerConfiguration().addInputChangedListener(this); + + // Listen for decorator changed to refresh the viewer's labels. + CVSUIPlugin.addPropertyChangeListener(this); + } + + private SyncInfoTree getSyncInfoSet() { + return getParticipant().getSubscriberSyncInfoCollector().getSyncInfoTree(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SubscriberParticipantPage#createSyncInfoSetCompareConfiguration() + */ + protected SubscriberPageDiffTreeViewerConfiguration createSyncInfoSetCompareConfiguration() { + if(config == null) { + config = new CVSSynchronizeViewCompareConfiguration(getSynchronizeView(), getParticipant()); + } + return config; + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.presentation.ISynchronizeModelChangeListener#inputChanged(org.eclipse.team.ui.synchronize.presentation.SynchronizeModelProvider) + */ + public void modelChanged(SynchronizeModelElement root) { + updateActionEnablement(root); } }
\ No newline at end of file diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/ChangeLogDiffNode.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/ChangeLogDiffNode.java new file mode 100644 index 000000000..896f1f7fa --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/ChangeLogDiffNode.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 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.ui.subscriber; + +import java.text.DateFormat; + +import org.eclipse.compare.structuremergeviewer.DiffNode; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.team.core.synchronize.SyncInfo; +import org.eclipse.team.internal.ccvs.core.ILogEntry; +import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; +import org.eclipse.team.internal.ccvs.ui.ICVSUIConstants; +import org.eclipse.team.ui.synchronize.viewers.SyncInfoModelElement; + +public class ChangeLogDiffNode extends SyncInfoModelElement { + + private ILogEntry logEntry; + + public ChangeLogDiffNode(DiffNode parent, ILogEntry logEntry) { + //super(parent, new SyncInfoTree(), ResourcesPlugin.getWorkspace().getRoot()); + super(null, null); + this.logEntry = logEntry; + } + + public ILogEntry getComment() { + return logEntry; + } + + public boolean equals(Object other) { + if(other == this) return true; + if(! (other instanceof ChangeLogDiffNode)) return false; + return ((ChangeLogDiffNode)other).getComment().equals(getComment()); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.model.IWorkbenchAdapter#getImageDescriptor(java.lang.Object) + */ + public ImageDescriptor getImageDescriptor(Object object) { + return CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_DATE); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.model.IWorkbenchAdapter#getLabel(java.lang.Object) + */ + public String getLabel(Object o) { + String date = DateFormat.getDateTimeInstance().format(logEntry.getDate()); + return date + ": " + logEntry.getComment() + " (" + logEntry.getAuthor() +")"; + } + + public void add(SyncInfo info) { + //((SubscriberSyncInfoSet)getSyncInfoTree()).add(info); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SyncInfoModelElement#toString() + */ + public String toString() { + return getLabel(null); + } +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/ChangeLogViewerInput.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/ChangeLogViewerInput.java new file mode 100644 index 000000000..c383732b5 --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/ChangeLogViewerInput.java @@ -0,0 +1,299 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 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.ui.subscriber; + +import java.util.*; + +import org.eclipse.compare.structuremergeviewer.IDiffElement; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.internal.ccvs.core.*; +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.ResourceSyncInfo; +import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; +import org.eclipse.team.ui.synchronize.viewers.*; +import org.eclipse.ui.model.IWorkbenchAdapter; +import org.eclipse.ui.progress.UIJob; + +/** + * It would be very useful to support showing changes grouped logically + * instead of grouped physically. This could be used for showing incoming + * changes and also for showing the results of comparisons. + * + * + 2003-12-09 Tuesday 6:04 jlemieux + * + Bug 3456: this was changed last night + * + org/eclipse/com/Main.java + * + org/blah/this/Other.txt + * + * {date/time, comment, user} -> {*files} + */ +public class ChangeLogViewerInput extends HierarchicalModelProvider { + + private Map commentRoots = new HashMap(); + private PendingUpdateAdapter pendingItem; + private boolean shutdown = false; + private FetchLogEntriesJob fetchLogEntriesJob; + + public static class DateComment { + Date date; + String comment; + private String user; + DateComment(Date date, String comment, String user) { + this.date = date; + this.comment = comment; + this.user = user; + } + + public boolean equals(Object obj) { + if(obj == this) return true; + if(! (obj instanceof DateComment)) return false; + DateComment other = (DateComment)obj; + + Calendar c1 = new GregorianCalendar(); + c1.setTime(date); + int year = c1.get(Calendar.YEAR); + int day = c1.get(Calendar.DAY_OF_YEAR); + + Calendar c2 = new GregorianCalendar(); + c2.setTime(other.date); + int yearOther = c2.get(Calendar.YEAR); + int dayOther = c2.get(Calendar.DAY_OF_YEAR); + + return year == yearOther && day == dayOther && comment.equals(other.comment) && + user.equals(other.user); + } + + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return date.hashCode() + comment.hashCode() + user.hashCode(); + } + } + + /** + * The PendingUpdateAdapter is a convenience object that can be used + * by a BaseWorkbenchContentProvider that wants to show a pending update. + */ + public static class PendingUpdateAdapter implements IWorkbenchAdapter, IAdaptable { + + /** + * Create a new instance of the receiver. + */ + public PendingUpdateAdapter() { + //No initial behavior + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + public Object getAdapter(Class adapter) { + if (adapter == IWorkbenchAdapter.class) + return this; + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.model.IWorkbenchAdapter#getChildren(java.lang.Object) + */ + public Object[] getChildren(Object o) { + return new Object[0]; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.model.IWorkbenchAdapter#getImageDescriptor(java.lang.Object) + */ + public ImageDescriptor getImageDescriptor(Object object) { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.model.IWorkbenchAdapter#getLabel(java.lang.Object) + */ + public String getLabel(Object o) { + return "Fetching logs from server. Please wait..."; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.model.IWorkbenchAdapter#getParent(java.lang.Object) + */ + public Object getParent(Object o) { + return null; + } + } + + private class FetchLogEntriesJob extends Job { + private SyncInfoSet set; + public FetchLogEntriesJob() { + super("Fetching CVS logs"); //$NON-NLS-1$; + } + public void setSyncInfoSet(SyncInfoSet set) { + this.set = set; + } + public IStatus run(IProgressMonitor monitor) { + if (set != null && !shutdown) { + final SyncInfoModelElement[] nodes = calculateRoots(getSyncInfoTree(), monitor); + UIJob updateUI = new UIJob("updating change log viewers") { + public IStatus runInUIThread(IProgressMonitor monitor) { + AbstractTreeViewer tree = getTreeViewer(); + if(pendingItem != null && tree != null && !tree.getControl().isDisposed()) { + tree.remove(pendingItem); + } + for (int i = 0; i < nodes.length; i++) { + addToViewer(nodes[i]); + buildModelObjects(nodes[i]); + } + return Status.OK_STATUS; + } + }; + updateUI.setSystem(true); + updateUI.schedule(); + } + return Status.OK_STATUS; + } + }; + + public ChangeLogViewerInput(SyncInfoTree set) { + super(set); + } + + /* + * (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.viewers.HierarchicalModelProvider#buildModelObjects(org.eclipse.compare.structuremergeviewer.DiffNode) + */ + protected IDiffElement[] buildModelObjects(SynchronizeModelElement node) { + /*if(node == this) { + UIJob job = new UIJob("") { + public IStatus runInUIThread(IProgressMonitor monitor) { + AbstractTreeViewer tree = getTreeViewer(); + if (tree != null && !tree.getControl().isDisposed()) { + if(pendingItem == null) { + pendingItem = new PendingUpdateAdapter(); + } + IDiffElement[] elements = getChildren(); + for (int i = 0; i < elements.length; i++) { + tree.remove(elements[i]); + } + tree.add(ChangeLogViewerInput.this, pendingItem); + } + return Status.OK_STATUS; + } + }; + job.schedule(); + + if(fetchLogEntriesJob == null) { + fetchLogEntriesJob = new FetchLogEntriesJob(); + } + if(fetchLogEntriesJob.getState() != Job.NONE) { + fetchLogEntriesJob.cancel(); + try { + fetchLogEntriesJob.join(); + } catch (InterruptedException e) { + } + } + fetchLogEntriesJob.setSyncInfoSet(getSyncInfoTree()); + fetchLogEntriesJob.schedule(); + } else { + return super.buildModelObjects(node); + }*/ + return new IDiffElement[0]; + } + + private SyncInfoModelElement[] calculateRoots(SyncInfoSet set, IProgressMonitor monitor) { + commentRoots.clear(); + /*SyncInfo[] infos = set.getSyncInfos(); + monitor.beginTask("fetching from server", set.size() * 100); + for (int i = 0; i < infos.length; i++) { + if(monitor.isCanceled()) { + break; + } + ILogEntry logEntry = getSyncInfoComment((CVSSyncInfo) infos[i], monitor); + if(logEntry != null) { + DateComment dateComment = new DateComment(logEntry.getDate(), logEntry.getComment(), logEntry.getAuthor()); + ChangeLogDiffNode changeRoot = (ChangeLogDiffNode) commentRoots.get(dateComment); + if (changeRoot == null) { + changeRoot = new ChangeLogDiffNode(this, logEntry); + commentRoots.put(dateComment, changeRoot); + } + changeRoot.add(infos[i]); + } + monitor.worked(100); + }*/ + return (ChangeLogDiffNode[]) commentRoots.values().toArray(new ChangeLogDiffNode[commentRoots.size()]); + } + + /** + * How do we tell which revision has the interesting log message? Use the later + * revision, since it probably has the most up-to-date comment. + */ + private ILogEntry getSyncInfoComment(CVSSyncInfo info, IProgressMonitor monitor) { + try { + if(info.getLocal().getType() != IResource.FILE) { + return null; + } + + ICVSRemoteResource remote = (ICVSRemoteResource)info.getRemote(); + ICVSRemoteResource base = (ICVSRemoteResource)info.getBase(); + ICVSRemoteResource local = (ICVSRemoteFile)CVSWorkspaceRoot.getRemoteResourceFor(info.getLocal()); + + String baseRevision = getRevisionString(base); + String remoteRevision = getRevisionString(remote); + String localRevision = getRevisionString(local); + // TODO: handle new files where there is no local or remote + boolean useRemote = true; + if(local != null && remote != null) { + useRemote = ResourceSyncInfo.isLaterRevision(remoteRevision, localRevision); + } else if(remote == null) { + useRemote = false; + } + if (useRemote) { + return ((RemoteFile) remote).getLogEntry(monitor); + } else if (local != null){ + return ((RemoteFile) local).getLogEntry(monitor); + } + return null; + } catch (CVSException e) { + CVSUIPlugin.log(e); + return null; + } + } + + private String getRevisionString(ICVSRemoteResource remoteFile) { + if(remoteFile instanceof RemoteFile) { + return ((RemoteFile)remoteFile).getRevision(); + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.views.HierarchicalModelProvider#syncSetChanged(org.eclipse.team.core.subscribers.ISyncInfoSetChangeEvent) + */ + protected void syncSetChanged(ISyncInfoSetChangeEvent event) { + reset(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.views.HierarchicalModelProvider#dispose() + */ + public void dispose() { + shutdown = true; + if(fetchLogEntriesJob != null && fetchLogEntriesJob.getState() != Job.NONE) { + fetchLogEntriesJob.cancel(); + } + super.dispose(); + } +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CompareParticipant.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CompareParticipant.java new file mode 100644 index 000000000..cb199eb5e --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CompareParticipant.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * 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.ui.subscriber; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.team.core.subscribers.Subscriber; +import org.eclipse.team.core.synchronize.SyncInfo; +import org.eclipse.team.core.synchronize.SyncInfoFilter; +import org.eclipse.team.internal.ccvs.core.CVSCompareSubscriber; +import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; +import org.eclipse.team.ui.TeamUI; +import org.eclipse.team.ui.synchronize.ISynchronizeParticipantDescriptor; +import org.eclipse.team.ui.synchronize.ISynchronizeView; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; +import org.eclipse.ui.part.IPageBookViewPage; + +public class CompareParticipant extends SubscriberParticipant { + + public final static String ID = "org.eclipse.team.cvs.ui.compare-participant"; //$NON-NLS-1$ + + private SyncInfoFilter contentComparison = new SyncInfoFilter() { + private SyncInfoFilter contentCompare = new SyncInfoFilter.ContentComparisonSyncInfoFilter(); + public boolean select(SyncInfo info, IProgressMonitor monitor) { + // Want to select infos whose contents do not match + return !contentCompare.select(info, monitor); + } + }; + + public CompareParticipant(CVSCompareSubscriber subscriber) { + super(); + setMode(BOTH_MODE); + setSubscriber(subscriber); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant#setSubscriber(org.eclipse.team.core.subscribers.Subscriber) + */ + protected void setSubscriber(Subscriber subscriber) { + super.setSubscriber(subscriber); + try { + ISynchronizeParticipantDescriptor descriptor = TeamUI.getSynchronizeManager().getParticipantDescriptor(ID); + setInitializationData(descriptor); + } catch (CoreException e) { + CVSUIPlugin.log(e); + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.AbstractSynchronizeParticipant#getName() + */ + public String getName() { + return getSubscriber().getName(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant#doCreatePage(org.eclipse.team.ui.synchronize.ISynchronizeView) + */ + protected IPageBookViewPage doCreatePage(ISynchronizeView view) { + return new CompareParticipantPage(this, view); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant#updateMode(int) + */ + protected void updateMode(int mode) { + // Don't allow modes to be used with this participant + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant#preCollectingChanges() + */ + protected void preCollectingChanges() { + super.preCollectingChanges(); + getSubscriberSyncInfoCollector().setFilter(contentComparison); + } +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CompareParticipantPage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CompareParticipantPage.java new file mode 100644 index 000000000..30ef265d1 --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CompareParticipantPage.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * 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.ui.subscriber; + +import org.eclipse.jface.action.*; +import org.eclipse.team.internal.ui.synchronize.actions.RemoveSynchronizeParticipantAction; +import org.eclipse.team.ui.synchronize.ISynchronizeView; +import org.eclipse.team.ui.synchronize.subscriber.DirectionFilterActionGroup; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; +import org.eclipse.ui.IActionBars; + +public class CompareParticipantPage extends CVSSynchronizeViewPage { + + private RemoveSynchronizeParticipantAction removeAction; + private DirectionFilterActionGroup modes; + private Action updateAdapter; + + public CompareParticipantPage(SubscriberParticipant participant, ISynchronizeView view) { + super(participant, view); + removeAction = new RemoveSynchronizeParticipantAction(getParticipant()); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.IPage#setActionBars(org.eclipse.ui.IActionBars) + */ + public void setActionBars(IActionBars actionBars) { + super.setActionBars(actionBars); + if (actionBars != null) { + IToolBarManager toolbar = actionBars.getToolBarManager(); + toolbar.add(new Separator()); + toolbar.add(removeAction); + } + } +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CompareRevertAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CompareRevertAction.java new file mode 100644 index 000000000..d4ac7fe78 --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CompareRevertAction.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * 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.ui.subscriber; + +import java.util.*; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.core.synchronize.SyncInfo; +import org.eclipse.team.core.synchronize.SyncInfoSet; +import org.eclipse.team.internal.ccvs.ui.Policy; + +/** + * Action in compare editor that reverts the local contents to match the contents on the server. + */ +public class CompareRevertAction extends CVSSubscriberAction { + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.subscriber.CVSSubscriberAction#run(org.eclipse.team.core.subscribers.MutableSyncInfoSet, org.eclipse.core.runtime.IProgressMonitor) + */ + protected void run(SyncInfoSet syncSet, IProgressMonitor monitor) throws TeamException { + SyncInfo[] changed = syncSet.getSyncInfos(); + if (changed.length == 0) return; + + // The list of sync resources to be updated using "cvs update" + List updateShallow = new ArrayList(); + // A list of sync resource folders which need to be created locally + // (incoming addition or previously pruned) + Set parentCreationElements = new HashSet(); + + for (int i = 0; i < changed.length; i++) { + SyncInfo changedNode = changed[i]; + + // Make sure that parent folders exist + SyncInfo parent = getParent(changedNode); + if (parent != null && isOutOfSync(parent)) { + // We need to ensure that parents that are either incoming folder additions + // or previously pruned folders are recreated. + parentCreationElements.add(parent); + } + + IResource resource = changedNode.getLocal(); + if (resource.getType() == IResource.FILE) { + if (changedNode.getLocal().exists()) { + updateShallow.add(changedNode); + } else if (changedNode.getRemote() != null) { + updateShallow.add(changedNode); + } + } else { + // Special handling for folders to support shallow operations on files + // (i.e. folder operations are performed using the sync info already + // contained in the sync info. + if (isOutOfSync(changedNode)) { + parentCreationElements.add(changedNode); + } + } + + } + try { + // Calculate the total amount of work needed + int work = updateShallow.size() * 100; + monitor.beginTask(null, work); + + if (parentCreationElements.size() > 0) { + makeInSync((SyncInfo[]) parentCreationElements.toArray(new SyncInfo[parentCreationElements.size()])); + } + if (updateShallow.size() > 0) { + runUpdate((SyncInfo[])updateShallow.toArray(new SyncInfo[updateShallow.size()]), Policy.subMonitorFor(monitor, updateShallow.size() * 100)); + } + } finally { + monitor.done(); + } + return; + } + + private void runUpdate(SyncInfo[] infos, IProgressMonitor monitor) throws TeamException { + monitor.beginTask(null, 100 * infos.length); + for (int i = 0; i < infos.length; i++) { + SyncInfo info = infos[i]; + makeRemoteLocal(info, Policy.subMonitorFor(monitor, 100)); + } + monitor.done(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.subscriber.CVSSubscriberAction#getJobName(org.eclipse.team.core.subscribers.SyncInfoSet) + */ + protected String getJobName(SyncInfoSet syncSet) { + return Policy.bind("CompareRevertAction.0", new Integer(syncSet.size()).toString()); //$NON-NLS-1$ + + } +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/MergeSynchronizePage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/MergeSynchronizePage.java index 868b65693..575ac0086 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/MergeSynchronizePage.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/MergeSynchronizePage.java @@ -13,11 +13,10 @@ package org.eclipse.team.internal.ccvs.ui.subscriber; import org.eclipse.jface.action.*; import org.eclipse.team.internal.ccvs.ui.Policy; import org.eclipse.team.internal.ui.Utils; -import org.eclipse.team.internal.ui.synchronize.sets.SubscriberInput; +import org.eclipse.team.internal.ui.synchronize.actions.RemoveSynchronizeParticipantAction; import org.eclipse.team.ui.synchronize.ISynchronizeView; -import org.eclipse.team.ui.synchronize.TeamSubscriberParticipant; -import org.eclipse.team.ui.synchronize.actions.DirectionFilterActionGroup; -import org.eclipse.team.ui.synchronize.actions.RemoveSynchronizeParticipantAction; +import org.eclipse.team.ui.synchronize.subscriber.DirectionFilterActionGroup; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; import org.eclipse.ui.IActionBars; @@ -27,16 +26,16 @@ public class MergeSynchronizePage extends CVSSynchronizeViewPage { private DirectionFilterActionGroup modes; private Action updateAdapter; - public MergeSynchronizePage(TeamSubscriberParticipant participant, ISynchronizeView view, SubscriberInput input) { - super(participant, view, input); + public MergeSynchronizePage(SubscriberParticipant participant, ISynchronizeView view) { + super(participant, view); removeAction = new RemoveSynchronizeParticipantAction(getParticipant()); - modes = new DirectionFilterActionGroup(getParticipant(), TeamSubscriberParticipant.INCOMING_MODE | TeamSubscriberParticipant.CONFLICTING_MODE); + modes = new DirectionFilterActionGroup(getParticipant(), SubscriberParticipant.INCOMING_MODE | SubscriberParticipant.CONFLICTING_MODE); MergeUpdateAction action = new MergeUpdateAction(); action.setPromptBeforeUpdate(true); updateAdapter = new CVSActionDelegate(action); Utils.initAction(updateAdapter, "action.SynchronizeViewUpdate.", Policy.getBundle()); //$NON-NLS-1$ - getParticipant().setMode(TeamSubscriberParticipant.INCOMING_MODE); + getParticipant().setMode(SubscriberParticipant.INCOMING_MODE); } /* (non-Javadoc) diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/MergeSynchronizeParticipant.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/MergeSynchronizeParticipant.java index cb1c469c5..877e8228d 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/MergeSynchronizeParticipant.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/MergeSynchronizeParticipant.java @@ -16,18 +16,18 @@ import java.util.List; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.*; -import org.eclipse.team.core.subscribers.TeamSubscriber; +import org.eclipse.team.core.subscribers.Subscriber; import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; import org.eclipse.team.internal.ccvs.ui.Policy; -import org.eclipse.team.internal.ui.synchronize.sets.SubscriberInput; import org.eclipse.team.ui.TeamUI; import org.eclipse.team.ui.synchronize.*; +import org.eclipse.team.ui.synchronize.subscriber.*; import org.eclipse.ui.IMemento; import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.IPageBookViewPage; -public class MergeSynchronizeParticipant extends TeamSubscriberParticipant { +public class MergeSynchronizeParticipant extends SubscriberParticipant { private final static String CTX_QUALIFIER = "qualifier"; //$NON-NLS-1$ private final static String CTX_LOCALNAME = "localname"; //$NON-NLS-1$ @@ -48,9 +48,9 @@ public class MergeSynchronizeParticipant extends TeamSubscriberParticipant { } /* (non-Javadoc) - * @see org.eclipse.team.ui.sync.TeamSubscriberParticipant#setSubscriber(org.eclipse.team.core.subscribers.TeamSubscriber) + * @see org.eclipse.team.ui.sync.SubscriberParticipant#setSubscriber(org.eclipse.team.core.subscribers.TeamSubscriber) */ - protected void setSubscriber(TeamSubscriber subscriber) { + protected void setSubscriber(Subscriber subscriber) { super.setSubscriber(subscriber); String id = CVSMergeSubscriber.QUALIFIED_NAME; try { @@ -85,8 +85,7 @@ public class MergeSynchronizeParticipant extends TeamSubscriberParticipant { */ public void saveState(IMemento memento) { super.saveState(memento); - SubscriberInput input = getInput(); - CVSMergeSubscriber s = (CVSMergeSubscriber)input.getSubscriber(); + CVSMergeSubscriber s = (CVSMergeSubscriber)getSubscriber(); QualifiedName sId = s.getId(); memento.putString(CTX_QUALIFIER, sId.getQualifier()); memento.putString(CTX_LOCALNAME, sId.getLocalName()); @@ -98,21 +97,21 @@ public class MergeSynchronizeParticipant extends TeamSubscriberParticipant { */ public void dispose() { super.dispose(); - ((CVSMergeSubscriber)getInput().getSubscriber()).cancel(); + ((CVSMergeSubscriber)getSubscriber()).cancel(); } /* (non-Javadoc) * @see org.eclipse.team.ui.synchronize.ISynchronizeParticipant#createPage(org.eclipse.team.ui.synchronize.ISynchronizeView) */ - public IPageBookViewPage createPage(ISynchronizeView view) { - return new MergeSynchronizePage(this, view, getInput()); + protected IPageBookViewPage doCreatePage(ISynchronizeView view) { + return new MergeSynchronizePage(this, view); } /* (non-Javadoc) * @see org.eclipse.team.ui.synchronize.ISynchronizeParticipant#getName() */ public String getName() { - return ((CVSMergeSubscriber)getInput().getSubscriber()).getName(); + return ((CVSMergeSubscriber)getSubscriber()).getName(); } /* (non-Javadoc) diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/MergeUpdateAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/MergeUpdateAction.java index 41422586c..7294626e8 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/MergeUpdateAction.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/MergeUpdateAction.java @@ -13,21 +13,19 @@ package org.eclipse.team.internal.ccvs.ui.subscriber; import java.util.ArrayList; import java.util.List; -import org.eclipse.core.resources.*; -import org.eclipse.core.runtime.*; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; 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.Subscriber; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.core.synchronize.FastSyncInfoFilter.OrSyncInfoFilter; +import org.eclipse.team.core.synchronize.FastSyncInfoFilter.SyncInfoDirectionFilter; import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.core.client.Command; import org.eclipse.team.internal.ccvs.core.client.Update; -import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; import org.eclipse.team.internal.ccvs.ui.Policy; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter; -import org.eclipse.team.ui.synchronize.actions.SyncInfoSet; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter.OrSyncInfoFilter; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter.SyncInfoDirectionFilter; /** * This action performs a "cvs update -j start -j end ..." to merge changes @@ -35,7 +33,7 @@ import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter.SyncInfoDirectionF */ public class MergeUpdateAction extends SafeUpdateAction { - TeamSubscriber currentSubcriber = null; + Subscriber currentSubcriber = null; /* (non-Javadoc) * @see org.eclipse.team.internal.ccvs.ui.subscriber.SafeUpdateAction#getOverwriteLocalChanges() @@ -47,9 +45,9 @@ public class MergeUpdateAction extends SafeUpdateAction { /* (non-Javadoc) * @see org.eclipse.team.ui.sync.SubscriberAction#getSyncInfoFilter() */ - protected SyncInfoFilter getSyncInfoFilter() { + protected FastSyncInfoFilter getSyncInfoFilter() { // Update works for all incoming and conflicting nodes - return new OrSyncInfoFilter(new SyncInfoFilter[] { + return new OrSyncInfoFilter(new FastSyncInfoFilter[] { new SyncInfoDirectionFilter(SyncInfo.INCOMING), new SyncInfoDirectionFilter(SyncInfo.CONFLICTING) }); @@ -90,7 +88,7 @@ public class MergeUpdateAction extends SafeUpdateAction { protected void runSafeUpdate(SyncInfo[] nodes, IProgressMonitor monitor) throws TeamException { if(nodes.length > 0) { // Assumption that all nodes are from the same subscriber. - currentSubcriber = nodes[0].getSubscriber(); + currentSubcriber = ((CVSSyncInfo)nodes[0]).getSubscriber(); if (!(currentSubcriber instanceof CVSMergeSubscriber)) { throw new CVSException(Policy.bind("MergeUpdateAction.invalidSubscriber", currentSubcriber.toString())); //$NON-NLS-1$ } @@ -154,65 +152,6 @@ public class MergeUpdateAction extends SafeUpdateAction { } } - /* - * If called on a new folder, the folder will become an outgoing addition. - */ - private void makeRemoteLocal(SyncInfo info, IProgressMonitor monitor) throws TeamException { - IRemoteResource remote = info.getRemote(); - IResource local = info.getLocal(); - try { - if(remote==null) { - local.delete(false, monitor); - } else { - if(remote.isContainer()) { - ensureContainerExists(info); - } else { - monitor.beginTask(null, 200); - try { - IFile localFile = (IFile)local; - if(local.exists()) { - localFile.setContents(remote.getContents(Policy.subMonitorFor(monitor, 100)), false /*don't force*/, true /*keep history*/, Policy.subMonitorFor(monitor, 100)); - } else { - ensureContainerExists(getParent(info)); - localFile.create(remote.getContents(Policy.subMonitorFor(monitor, 100)), false /*don't force*/, Policy.subMonitorFor(monitor, 100)); - } - } finally { - monitor.done(); - } - } - } - } catch(CoreException e) { - throw new CVSException(Policy.bind("UpdateMergeActionProblems_merging_remote_resources_into_workspace_1"), e); //$NON-NLS-1$ - } - } - - private boolean ensureContainerExists(SyncInfo info) throws TeamException { - IResource local = info.getLocal(); - // make sure that the parent exists - if (!local.exists()) { - if (!ensureContainerExists(getParent(info))) { - return false; - } - } - // make sure that the folder sync info is set; - if (isOutOfSync(info)) { - if (info instanceof CVSSyncInfo) { - CVSSyncInfo cvsInfo = (CVSSyncInfo)info; - IStatus status = cvsInfo.makeInSync(); - if (status.getSeverity() == IStatus.ERROR) { - logError(status); - return false; - } - } - } - // create the folder if it doesn't exist - ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor((IContainer)local); - if (!cvsFolder.exists()) { - cvsFolder.mkdir(); - } - return true; - } - /* (non-Javadoc) * @see org.eclipse.team.internal.ccvs.ui.subscriber.CVSSubscriberAction#getJobName(org.eclipse.team.ui.sync.SyncInfoSet) */ diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/OverrideAndCommitAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/OverrideAndCommitAction.java index 915a207fd..be2ac3278 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/OverrideAndCommitAction.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/OverrideAndCommitAction.java @@ -10,17 +10,15 @@ *******************************************************************************/ package org.eclipse.team.internal.ccvs.ui.subscriber; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter; -import org.eclipse.team.ui.synchronize.actions.SyncInfoSet; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter.SyncInfoDirectionFilter; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.core.synchronize.FastSyncInfoFilter.SyncInfoDirectionFilter; public class OverrideAndCommitAction extends SubscriberCommitAction { /* (non-Javadoc) * @see org.eclipse.team.ui.sync.SubscriberAction#getSyncInfoFilter() */ - protected SyncInfoFilter getSyncInfoFilter() { + protected FastSyncInfoFilter getSyncInfoFilter() { return new SyncInfoDirectionFilter(new int[] {SyncInfo.CONFLICTING, SyncInfo.INCOMING}); } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/OverrideAndUpdateAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/OverrideAndUpdateAction.java index 3ebd48e5a..09207c4f4 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/OverrideAndUpdateAction.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/OverrideAndUpdateAction.java @@ -17,13 +17,11 @@ import java.util.List; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.core.synchronize.FastSyncInfoFilter.SyncInfoDirectionFilter; import org.eclipse.team.internal.ccvs.core.CVSException; import org.eclipse.team.internal.ccvs.ui.Policy; import org.eclipse.team.internal.ccvs.ui.operations.OverrideAndUpdateOperation; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter; -import org.eclipse.team.ui.synchronize.actions.SyncInfoSet; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter.SyncInfoDirectionFilter; /** * Runs an update command that will prompt the user for overwritting local @@ -34,15 +32,15 @@ public class OverrideAndUpdateAction extends CVSSubscriberAction { /* (non-Javadoc) * @see org.eclipse.team.ui.sync.SubscriberAction#getSyncInfoFilter() */ - protected SyncInfoFilter getSyncInfoFilter() { + protected FastSyncInfoFilter getSyncInfoFilter() { return new SyncInfoDirectionFilter(new int[] {SyncInfo.CONFLICTING, SyncInfo.OUTGOING}); } - private SyncInfoFilter getConflictingAdditionFilter() { - return new SyncInfoFilter.AndSyncInfoFilter( - new SyncInfoFilter[] { - new SyncInfoFilter.SyncInfoDirectionFilter(new int[] {SyncInfo.CONFLICTING}), - new SyncInfoFilter.SyncInfoChangeTypeFilter(new int[] {SyncInfo.ADDITION}) + private FastSyncInfoFilter getConflictingAdditionFilter() { + return new FastSyncInfoFilter.AndSyncInfoFilter( + new FastSyncInfoFilter[] { + new FastSyncInfoFilter.SyncInfoDirectionFilter(new int[] {SyncInfo.CONFLICTING}), + new FastSyncInfoFilter.SyncInfoChangeTypeFilter(new int[] {SyncInfo.ADDITION}) }); } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SafeUpdateAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SafeUpdateAction.java index a36f6b82a..895175342 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SafeUpdateAction.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SafeUpdateAction.java @@ -11,11 +11,7 @@ package org.eclipse.team.internal.ccvs.ui.subscriber; import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; @@ -23,22 +19,15 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; -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.ICVSFile; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.core.synchronize.FastSyncInfoFilter.*; +import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption; import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; import org.eclipse.team.internal.ccvs.ui.Policy; import org.eclipse.team.internal.ccvs.ui.operations.UpdateOnlyMergableOperation; import org.eclipse.team.internal.ui.TeamUIPlugin; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter; -import org.eclipse.team.ui.synchronize.actions.SyncInfoSet; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter.AndSyncInfoFilter; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter.OrSyncInfoFilter; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter.SyncInfoDirectionFilter; /** * This update action will update all mergable resources first and then prompt the @@ -59,7 +48,7 @@ public abstract class SafeUpdateAction extends CVSSubscriberAction { try { if(! promptIfNeeded(syncSet)) return; // First, remove any known failure cases - SyncInfoFilter failFilter = getKnownFailureCases(); + FastSyncInfoFilter failFilter = getKnownFailureCases(); SyncInfo[] willFail = syncSet.getNodes(failFilter); syncSet.rejectNodes(failFilter); skippedFiles.clear(); @@ -75,9 +64,9 @@ public abstract class SafeUpdateAction extends CVSSubscriberAction { final SyncInfoSet failedSet = createFailedSet(syncSet, willFail, (IFile[]) skippedFiles.toArray(new IFile[skippedFiles.size()])); // Remove all these from the original sync set - syncSet.rejectNodes(new SyncInfoFilter() { + syncSet.rejectNodes(new FastSyncInfoFilter() { public boolean select(SyncInfo info) { - return failedSet.getNodeFor(info.getLocal()) != null; + return failedSet.getSyncInfo(info.getLocal()) != null; } }); @@ -87,7 +76,9 @@ public abstract class SafeUpdateAction extends CVSSubscriberAction { // Ask the user if a replace should be performed on the remaining nodes if(promptForOverwrite(failedSet)) { overwriteUpdate(failedSet, Policy.subMonitorFor(monitor, willFail.length * 100)); - syncSet.addAll(failedSet); + if (!failedSet.isEmpty()) { + syncSet.addAll(failedSet); + } } } else { // Warn the user that some nodes could not be updated. This can happen if there are @@ -211,24 +202,24 @@ public abstract class SafeUpdateAction extends CVSSubscriberAction { * Return a filter which selects the cases that we know ahead of time * will fail on an update */ - protected SyncInfoFilter getKnownFailureCases() { - return new OrSyncInfoFilter(new SyncInfoFilter[] { + protected FastSyncInfoFilter getKnownFailureCases() { + return new OrSyncInfoFilter(new FastSyncInfoFilter[] { // Conflicting additions of files will fail - new AndSyncInfoFilter(new SyncInfoFilter[] { - SyncInfoFilter.getDirectionAndChangeFilter(SyncInfo.CONFLICTING, SyncInfo.ADDITION), - new SyncInfoFilter() { + new AndSyncInfoFilter(new FastSyncInfoFilter[] { + FastSyncInfoFilter.getDirectionAndChangeFilter(SyncInfo.CONFLICTING, SyncInfo.ADDITION), + new FastSyncInfoFilter() { public boolean select(SyncInfo info) { return info.getLocal().getType() == IResource.FILE; } } }), // Conflicting changes involving a deletion on one side will aways fail - new AndSyncInfoFilter(new SyncInfoFilter[] { - SyncInfoFilter.getDirectionAndChangeFilter(SyncInfo.CONFLICTING, SyncInfo.CHANGE), - new SyncInfoFilter() { + new AndSyncInfoFilter(new FastSyncInfoFilter[] { + FastSyncInfoFilter.getDirectionAndChangeFilter(SyncInfo.CONFLICTING, SyncInfo.CHANGE), + new FastSyncInfoFilter() { public boolean select(SyncInfo info) { - IRemoteResource remote = info.getRemote(); - IRemoteResource base = info.getBase(); + IResourceVariant remote = info.getRemote(); + IResourceVariant base = info.getBase(); if (info.getLocal().exists()) { // local != base and no remote will fail return (base != null && remote == null); @@ -241,9 +232,9 @@ public abstract class SafeUpdateAction extends CVSSubscriberAction { }), // Conflicts where the file type is binary will work but are not merged // so they should be skipped - new AndSyncInfoFilter(new SyncInfoFilter[] { - SyncInfoFilter.getDirectionAndChangeFilter(SyncInfo.CONFLICTING, SyncInfo.CHANGE), - new SyncInfoFilter() { + new AndSyncInfoFilter(new FastSyncInfoFilter[] { + FastSyncInfoFilter.getDirectionAndChangeFilter(SyncInfo.CONFLICTING, SyncInfo.CHANGE), + new FastSyncInfoFilter() { public boolean select(SyncInfo info) { IResource local = info.getLocal(); if (local.getType() == IResource.FILE) { @@ -276,7 +267,7 @@ public abstract class SafeUpdateAction extends CVSSubscriberAction { List result = new ArrayList(); for (int i = 0; i < files.length; i++) { IFile file = files[i]; - SyncInfo resource = syncSet.getNodeFor(file); + SyncInfo resource = syncSet.getSyncInfo(file); if (resource != null) result.add(resource); } for (int i = 0; i < willFail.length; i++) { @@ -293,7 +284,7 @@ public abstract class SafeUpdateAction extends CVSSubscriberAction { final int[] result = new int[] {Dialog.CANCEL}; TeamUIPlugin.getStandardDisplay().syncExec(new Runnable() { public void run() { - MessageDialog.openInformation(shell, + MessageDialog.openInformation(getShell(), Policy.bind("SafeUpdateAction.warnFilesWithConflictsTitle"), //$NON-NLS-1$ Policy.bind("SafeUpdateAction.warnFilesWithConflictsDescription")); //$NON-NLS-1$ } @@ -366,8 +357,8 @@ public abstract class SafeUpdateAction extends CVSSubscriberAction { TeamUIPlugin.getStandardDisplay().syncExec(new Runnable() { public void run() { String sizeString = Integer.toString(set.size()); - String message = set.size() > 1 ? Policy.bind("UpdateAction.promptForUpdateSeveral", sizeString) : Policy.bind("UpdateAction.promptForUpdateOne", sizeString); - result[0] = MessageDialog.openQuestion(getShell(), Policy.bind("UpdateAction.promptForUpdateTitle", sizeString), message); + String message = set.size() > 1 ? Policy.bind("UpdateAction.promptForUpdateSeveral", sizeString) : Policy.bind("UpdateAction.promptForUpdateOne", sizeString); //$NON-NLS-1$ //$NON-NLS-2$ + result[0] = MessageDialog.openQuestion(getShell(), Policy.bind("UpdateAction.promptForUpdateTitle", sizeString), message); //$NON-NLS-1$ } }); } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SubscriberCommitAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SubscriberCommitAction.java index 2216abdf3..9d1376ce3 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SubscriberCommitAction.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SubscriberCommitAction.java @@ -19,11 +19,9 @@ import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.widgets.Shell; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.ICVSFile; -import org.eclipse.team.internal.ccvs.core.ICVSFolder; -import org.eclipse.team.internal.ccvs.core.ICVSResource; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.core.synchronize.FastSyncInfoFilter.SyncInfoDirectionFilter; +import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; @@ -31,9 +29,6 @@ import org.eclipse.team.internal.ccvs.ui.Policy; import org.eclipse.team.internal.ccvs.ui.repo.RepositoryManager; import org.eclipse.team.internal.ccvs.ui.sync.ToolTipMessageDialog; import org.eclipse.team.internal.ui.Utils; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter; -import org.eclipse.team.ui.synchronize.actions.SyncInfoSet; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter.SyncInfoDirectionFilter; public class SubscriberCommitAction extends CVSSubscriberAction { @@ -42,15 +37,15 @@ public class SubscriberCommitAction extends CVSSubscriberAction { /* (non-Javadoc) * @see org.eclipse.team.ui.sync.SubscriberAction#getSyncInfoFilter() */ - protected SyncInfoFilter getSyncInfoFilter() { + protected FastSyncInfoFilter getSyncInfoFilter() { return new SyncInfoDirectionFilter(new int[] {SyncInfo.OUTGOING}); } /* (non-Javadoc) - * @see org.eclipse.team.internal.ccvs.ui.subscriber.CVSSubscriberAction#getFilteredSyncInfoSet(org.eclipse.team.internal.ui.sync.views.SyncInfo[]) + * @see org.eclipse.team.ui.synchronize.subscriber.SubscriberAction#makeSyncInfoSetFromSelection(org.eclipse.team.core.synchronize.SyncInfo[]) */ - protected SyncInfoSet getFilteredSyncInfoSet(SyncInfo[] selectedResources) { - SyncInfoSet syncSet = super.getFilteredSyncInfoSet(selectedResources); + protected SyncInfoSet makeSyncInfoSetFromSelection(SyncInfo[] infos) { + SyncInfoSet syncSet = new SyncInfoSet(infos); if (!promptForConflictHandling(syncSet)) return null; try { if (!promptForUnaddedHandling(syncSet)) return null; @@ -98,7 +93,7 @@ public class SubscriberCommitAction extends CVSSubscriberAction { if (!included) resourcesToRemove.add(unaddedResource); } - syncSet.removeResources((IResource[]) resourcesToRemove.toArray(new IResource[resourcesToRemove.size()])); + syncSet.removeAll((IResource[]) resourcesToRemove.toArray(new IResource[resourcesToRemove.size()])); } return true; } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SubscriberConfirmMergedAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SubscriberConfirmMergedAction.java index 5fb4b7d14..b75860fdc 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SubscriberConfirmMergedAction.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SubscriberConfirmMergedAction.java @@ -13,16 +13,12 @@ package org.eclipse.team.internal.ccvs.ui.subscriber; 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.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.CVSSyncInfo; -import org.eclipse.team.internal.ccvs.core.ICVSFolder; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.core.synchronize.FastSyncInfoFilter.SyncInfoDirectionFilter; +import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; import org.eclipse.team.internal.ccvs.ui.Policy; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter; -import org.eclipse.team.ui.synchronize.actions.SyncInfoSet; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter.SyncInfoDirectionFilter; /** * This action marks the local resource as merged by updating the base @@ -33,7 +29,7 @@ public class SubscriberConfirmMergedAction extends CVSSubscriberAction { /* (non-Javadoc) * @see org.eclipse.team.ui.sync.SubscriberAction#getSyncInfoFilter() */ - protected SyncInfoFilter getSyncInfoFilter() { + protected FastSyncInfoFilter getSyncInfoFilter() { return new SyncInfoDirectionFilter(new int[] {SyncInfo.CONFLICTING}); } @@ -69,8 +65,8 @@ public class SubscriberConfirmMergedAction extends CVSSubscriberAction { ICVSFolder parent = CVSWorkspaceRoot.getCVSFolderFor(cvsInfo.getLocal().getParent()); if (!parent.isCVSFolder()) { // the parents must be made outgoing before the child can - SyncInfo parentInfo = cvsInfo.getSubscriber().getSyncInfo(parent.getIResource(), Policy.subMonitorFor(monitor, 10)); - if (!makeOutgoing(parentInfo, Policy.subMonitorFor(monitor, 10))) { + SyncInfo parentInfo = cvsInfo.getSubscriber().getSyncInfo(parent.getIResource()); + if (!makeOutgoing(parentInfo, Policy.subMonitorFor(monitor, 20))) { return false; } } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SyncInfoSetDetailsDialog.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SyncInfoSetDetailsDialog.java index f3fddaadf..38c124996 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SyncInfoSetDetailsDialog.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SyncInfoSetDetailsDialog.java @@ -12,24 +12,16 @@ package org.eclipse.team.internal.ccvs.ui.subscriber; import org.eclipse.core.resources.IResource; import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.viewers.CheckboxTableViewer; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.*; import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.*; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.team.core.subscribers.SyncInfo; +import org.eclipse.swt.widgets.*; +import org.eclipse.team.core.synchronize.*; import org.eclipse.team.internal.ccvs.ui.AdaptableResourceList; import org.eclipse.team.internal.ccvs.ui.Policy; import org.eclipse.team.internal.ui.dialogs.DetailsDialog; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter; -import org.eclipse.team.ui.synchronize.actions.SyncInfoSet; import org.eclipse.ui.model.WorkbenchContentProvider; import org.eclipse.ui.model.WorkbenchLabelProvider; @@ -189,7 +181,7 @@ public abstract class SyncInfoSetDetailsDialog extends DetailsDialog { protected void filterSyncSet() { // Keep only the checked resources if (selectedResources != null) { - getSyncSet().selectNodes(new SyncInfoFilter() { + getSyncSet().selectNodes(new FastSyncInfoFilter() { public boolean select(SyncInfo info) { IResource local = info.getLocal(); for (int i = 0; i < selectedResources.length; i++) { diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SynchronizeViewActionDelagate.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SynchronizeViewActionDelagate.java deleted file mode 100644 index 21d241ebb..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SynchronizeViewActionDelagate.java +++ /dev/null @@ -1,37 +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.ui.subscriber; - -import org.eclipse.jface.action.Action; -import org.eclipse.team.internal.ui.synchronize.sets.ISyncSetChangedListener; -import org.eclipse.team.internal.ui.synchronize.sets.SubscriberInput; -import org.eclipse.team.internal.ui.synchronize.sets.SyncSetChangedEvent; -import org.eclipse.ui.actions.ActionDelegate; - -public abstract class SynchronizeViewActionDelagate extends Action implements ISyncSetChangedListener { - - private SubscriberInput input; - private ActionDelegate delegate; - - public SynchronizeViewActionDelagate(SubscriberInput input, ActionDelegate delegate) { - super(); - this.delegate = delegate; - this.input = input; - input.getFilteredSyncSet().addSyncSetChangedListener(this); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ui.sync.sets.ISyncSetChangedListener#syncSetChanged(org.eclipse.team.internal.ui.sync.sets.SyncSetChangedEvent) - */ - public void syncSetChanged(SyncSetChangedEvent event) { - setEnabled(isEnabled()); - } -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/UpdateDialog.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/UpdateDialog.java index b9926de6e..61a273a1a 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/UpdateDialog.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/UpdateDialog.java @@ -15,7 +15,7 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Shell; -import org.eclipse.team.ui.synchronize.actions.SyncInfoSet; +import org.eclipse.team.core.synchronize.SyncInfoSet; import org.eclipse.team.internal.ccvs.ui.Policy; /** diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceSynchronizePage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceSynchronizePage.java index 668dbdd74..d05923569 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceSynchronizePage.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceSynchronizePage.java @@ -13,10 +13,9 @@ package org.eclipse.team.internal.ccvs.ui.subscriber; import org.eclipse.jface.action.*; import org.eclipse.team.internal.ccvs.ui.Policy; import org.eclipse.team.internal.ui.Utils; -import org.eclipse.team.internal.ui.synchronize.sets.SubscriberInput; import org.eclipse.team.ui.synchronize.ISynchronizeView; -import org.eclipse.team.ui.synchronize.TeamSubscriberParticipant; -import org.eclipse.team.ui.synchronize.actions.DirectionFilterActionGroup; +import org.eclipse.team.ui.synchronize.subscriber.DirectionFilterActionGroup; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; import org.eclipse.ui.IActionBars; public class WorkspaceSynchronizePage extends CVSSynchronizeViewPage { @@ -26,9 +25,9 @@ public class WorkspaceSynchronizePage extends CVSSynchronizeViewPage { private Action commitToolbar; private Action updateToolbar; - public WorkspaceSynchronizePage(TeamSubscriberParticipant page, ISynchronizeView view, SubscriberInput input) { - super(page, view, input); - modes = new DirectionFilterActionGroup(getParticipant(), TeamSubscriberParticipant.ALL_MODES); + public WorkspaceSynchronizePage(SubscriberParticipant page, ISynchronizeView view) { + super(page, view); + modes = new DirectionFilterActionGroup(getParticipant(), SubscriberParticipant.ALL_MODES); commitToolbar = new CVSActionDelegate(new SubscriberCommitAction()); WorkspaceUpdateAction action = new WorkspaceUpdateAction(); @@ -37,6 +36,9 @@ public class WorkspaceSynchronizePage extends CVSSynchronizeViewPage { Utils.initAction(commitToolbar, "action.SynchronizeViewCommit.", Policy.getBundle()); //$NON-NLS-1$ Utils.initAction(updateToolbar, "action.SynchronizeViewUpdate.", Policy.getBundle()); //$NON-NLS-1$ + + // force enablement to be update on action delegates + //syncSetChanged(null); } /* (non-Javadoc) diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceSynchronizeParticipant.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceSynchronizeParticipant.java index 738ded4c9..bde067da7 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceSynchronizeParticipant.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceSynchronizeParticipant.java @@ -10,24 +10,23 @@ *******************************************************************************/ package org.eclipse.team.internal.ccvs.ui.subscriber; -import org.eclipse.team.core.subscribers.TeamSubscriber; +import org.eclipse.team.core.subscribers.Subscriber; import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin; -import org.eclipse.team.internal.ui.TeamUIPlugin; import org.eclipse.team.ui.synchronize.ISynchronizeView; -import org.eclipse.team.ui.synchronize.TeamSubscriberParticipant; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; import org.eclipse.ui.IMemento; import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.IPageBookViewPage; -public class WorkspaceSynchronizeParticipant extends TeamSubscriberParticipant { +public class WorkspaceSynchronizeParticipant extends SubscriberParticipant { public final static String ID = "org.eclipse.team.cvs.ui.cvsworkspace-participant"; //$NON-NLS-1$ /* (non-Javadoc) - * @see org.eclipse.team.ui.synchronize.ISynchronizeParticipant#createPage(org.eclipse.team.ui.synchronize.ISynchronizeView) + * @see org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant#doCreatePage(org.eclipse.team.ui.synchronize.ISynchronizeView) */ - public IPageBookViewPage createPage(ISynchronizeView view) { - return new WorkspaceSynchronizePage(this, view, getInput()); + protected IPageBookViewPage doCreatePage(ISynchronizeView view) { + return new WorkspaceSynchronizePage(this, view); } /* (non-Javadoc) @@ -35,8 +34,7 @@ public class WorkspaceSynchronizeParticipant extends TeamSubscriberParticipant { */ public void init(IMemento memento) throws PartInitException { super.init(memento); - TeamSubscriber subscriber = CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber(); + Subscriber subscriber = CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber(); setSubscriber(subscriber); - TeamUIPlugin.getPlugin().getRefreshJob().addSubscriberInput(getInput()); } }
\ No newline at end of file diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceUpdateAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceUpdateAction.java index a6b604f8d..0ec55baf5 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceUpdateAction.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceUpdateAction.java @@ -12,22 +12,18 @@ package org.eclipse.team.internal.ccvs.ui.subscriber; import java.lang.reflect.InvocationTargetException; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.*; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.core.synchronize.FastSyncInfoFilter.SyncInfoDirectionFilter; import org.eclipse.team.internal.ccvs.core.CVSException; import org.eclipse.team.internal.ccvs.core.client.Command; import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption; import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; import org.eclipse.team.internal.ccvs.ui.Policy; import org.eclipse.team.internal.ccvs.ui.operations.ReplaceOperation; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter; -import org.eclipse.team.ui.synchronize.actions.SyncInfoSet; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter.SyncInfoDirectionFilter; /** * This action performs an update for the CVSWorkspaceSubscriber. @@ -37,7 +33,7 @@ public class WorkspaceUpdateAction extends SafeUpdateAction { /* (non-Javadoc) * @see org.eclipse.team.ui.sync.SubscriberAction#getSyncInfoFilter() */ - protected SyncInfoFilter getSyncInfoFilter() { + protected FastSyncInfoFilter getSyncInfoFilter() { return new SyncInfoDirectionFilter(new int[] {SyncInfo.INCOMING, SyncInfo.CONFLICTING}); } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/SharingWizard.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/SharingWizard.java index 696a9dc81..51505e727 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/SharingWizard.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/SharingWizard.java @@ -52,10 +52,11 @@ import org.eclipse.team.internal.ccvs.ui.Policy; import org.eclipse.team.internal.ccvs.ui.TagSelectionDialog; import org.eclipse.team.internal.ccvs.ui.operations.ReconcileProjectOperation; import org.eclipse.team.internal.ccvs.ui.operations.ShareProjectOperation; +import org.eclipse.team.internal.ccvs.ui.subscriber.WorkspaceSynchronizeParticipant; import org.eclipse.team.ui.IConfigurationWizard; -import org.eclipse.team.ui.synchronize.TeamSubscriberParticipant; +import org.eclipse.team.ui.TeamUI; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkingSet; /** * This wizard helps the user to import a new project in their workspace @@ -89,6 +90,7 @@ public class SharingWizard extends Wizard implements IConfigurationWizard { setDialogSettings(section); setNeedsProgressMonitor(true); setWindowTitle(Policy.bind("SharingWizard.title")); //$NON-NLS-1$ + //set } public void addPages() { @@ -120,6 +122,7 @@ public class SharingWizard extends Wizard implements IConfigurationWizard { modulePage = new ModuleSelectionPage("modulePage", Policy.bind("SharingWizard.enterModuleName"), sharingImage); //$NON-NLS-1$ //$NON-NLS-2$ modulePage.setDescription(Policy.bind("SharingWizard.enterModuleNameDescription")); //$NON-NLS-1$ addPage(modulePage); + WorkspaceSynchronizeParticipant p = (WorkspaceSynchronizeParticipant)TeamUI.getSynchronizeManager().find(WorkspaceSynchronizeParticipant.ID)[0]; finishPage = new SharingWizardFinishPage("finishPage", Policy.bind("SharingWizard.readyToFinish"), sharingImage); //$NON-NLS-1$ //$NON-NLS-2$ finishPage.setDescription(Policy.bind("SharingWizard.readyToFinishDescription")); //$NON-NLS-1$ addPage(finishPage); @@ -304,8 +307,7 @@ public class SharingWizard extends Wizard implements IConfigurationWizard { throw new InvocationTargetException(e); } } - IWorkingSet workingSet = CVSUIPlugin.getWorkingSet(new IResource[] {project}, Policy.bind("SyncAction.workingSetName")); //$NON-NLS-1$ - CVSUIPlugin.showInSyncView(getContainer().getShell(), null, workingSet, TeamSubscriberParticipant.OUTGOING_MODE); + CVSUIPlugin.showInSyncView(getContainer().getShell(), null, SubscriberParticipant.OUTGOING_MODE); } } catch (InterruptedException e) { return true; diff --git a/bundles/org.eclipse.team.ui/.project b/bundles/org.eclipse.team.ui/.project index c8536e10a..7093fb2b5 100644 --- a/bundles/org.eclipse.team.ui/.project +++ b/bundles/org.eclipse.team.ui/.project @@ -15,6 +15,7 @@ <project>org.eclipse.ui.ide</project> <project>org.eclipse.ui.views</project> <project>org.eclipse.ui.workbench.texteditor</project> + <project>org.eclipse.update.ui.forms</project> </projects> <buildSpec> <buildCommand> diff --git a/bundles/org.eclipse.team.ui/DESIGN.TXT b/bundles/org.eclipse.team.ui/DESIGN.TXT new file mode 100644 index 000000000..91dffbe4a --- /dev/null +++ b/bundles/org.eclipse.team.ui/DESIGN.TXT @@ -0,0 +1,93 @@ +
+======================
+ core
+======================
+SyncInfo
+- represents relative sync of local and remote gives access to resources
+
+TeamSubscriber
+- creates sync infos
+
+SyncInfoSet/MutableSyncInfoSet (optimized collection of sync infos - immutable)
+
+SyncInfoFilter (filtering of sync sets used by actions and creation of sync sets)
+
+SyncInfoCollector (collects sync infos from subscriber, and optionally from workspace. Uses background thread to collect and calculate changes. Is updated automatically with changes)
+
+FilteredSyncInfoSet (filters a provided sync info set with a given filter and possible roots)
+
+======================
+ ui
+======================
+
+ISynchronizeManager (manages the lifesycle of synchronize participants)
+
+ISynchronizeView
+
+ISynchronizeParticipant (shows in the sync view, has a mode, working set, and creates a page with the UI pieces)
+
+Modes in sync view (DirectionFilterActionGroup)
+
+SyncInfoSetCompareConfiguration (encapsulates navigation, menus, content, label providers)this
+ is used to configure a viewer in different ways based on it's use.
+
+SyncInfoDiffTreeViewer/SyncInfoDiffCheckboxViewer (shows diff nodes)
+
+SyncInfoDiffNode -> DiffNode
+
+SyncInfoSetCompareInput
+
+
+
+DiffNode
+SyncInfoDiffNode
+
+Viewer
+ContentProvider
+Sorter
+LabelProvider
+ViewerInput
+
+1. sync set is created
+2. decide how to model the sync set (hierachy, compressed, change log...) sorter...
+3. hook up chagnen listener
+4. ensure model doesn't change while building it?
+5. update model dynamically
+6. dispose of listener when input changes
+
+SuperCharged MVC
+================
+
+Sync Set Compare Input (displays a diff tree viewer with the compare panes)
+
+Sync Info Compare Input (displays a compare pane for one sync info)
+
+Viewer (viewers) -> view configurators (menus, content provider, label provider, controller)
+
+Viewer Model (diff nodes) logical structure of sync info
+
+Viewer Input (creates viewer model, keeps it up-to-date, sorter)
+
+Data (sync info, sync info set)
+
+1. when does the viewer model get created, it is implementation dependant
+2. why is creating the viewer model takes a while.
+
+How is progress shown?
+======================
+
+1. actions that run jobs that affect a view's content should schedule in the view
+ - object contributions, or delegates get this for free via SubscriberAction which
+ has a schedule which will schedule via the associated IWorkbenchPart.
+ - actions programatically added to a view should be initialized with the view part or view site
+ so that it can run the job in the view's context.
+ - this will get you (1) the view icon change hint, (2) the half-busy cursor
+2. jobs should provide meaningful progress shown in progress view
+ - this will get you (1) a job listed in the progress support showing that something is happening
+3. if working on syncinfodiffnodes in the background you can mark the nodes as working as a hint
+ to the UI to display them differently (e.g. should make this adapter specific)
+ - this will get you (1) nodes in the sync view showing that they are being worked on
+4. Use progress groups in refresh to show remote refresh and sync calculation as one work item.
+ - this will get you (1) one entry in the progress view for both the remote refresh and background
+ processing of sync states. no more updating sync view message.
+
diff --git a/bundles/org.eclipse.team.ui/TODO-syncview.txt b/bundles/org.eclipse.team.ui/TODO-syncview.txt new file mode 100644 index 000000000..523df08b3 --- /dev/null +++ b/bundles/org.eclipse.team.ui/TODO-syncview.txt @@ -0,0 +1,173 @@ +====================================================================== + EXAMPLE TEAM UI API USAGES +====================================================================== +1. embeding sync viewer in dialog/wizard +2. added a new content provider (logical views of sync info changes) +3. adding custom label decorations +4. actions/menus +5. fetching sync info set without instantiating a participant +6. fetch and wait for the event collector to finish processing the changes +7. showing in a diff viewer either a static model (doesn't update when changes occur) or dynamic + +====================================================================== + PR LIST (07-01-2004) +====================================================================== + +x P3 schedule support by participant. + this requires changing the refresh jobs to accept scheduling different jobs. Essentially being able to have an + ordered *queue of refreshes. Also, participant will need a schedule object to encapsulate the schedule logic. + +x P3 status message could be more precise instead of simply "Working". But to do this we need access to the job progress monitor + and it isn't available API from the UI. (removed status in sync view, progress will be shown in the progress shell). + +x P1 end of refresh prompt should be a property change notice, and let the participant decide what to do! + +x P2 decide overview page contents and how it should be used + +x remove duplicated tree/table viewers classes. the orignial ones simply have the INavigable behavior. + +x P1 make changes section only be a pagebook. this would easily allow adding any number of composites to the page? + should look at memory consuption and ensure that we are disposing properly! + +- compareeditorinput fetcheds remote content outside of a progress monitor + +x decorations for SyncInfoDiffElements (of which type.. project persistent property setting?) +x labels for compare editors (text merge viewers and title for diff viewer) + +x generic navigate support for SyncInfoDiffTreeViewer, PRd compare for API support + +x readonly state for compare panes + +- progress support added when fetching (e.g. caching contents in ITypedElement). This will require compare to add some API. + +x INavigable in compare needs to be made API. + +- details dialog needs to create composites once then display them. Or only create once!!!! + +x sync set filtering creation must be more precise. For example you should be able to specify a root and a direction. + +x cvs update/commit action in sync view toolbar are not updating their state anymore :( + +x P3 mode switching at the end of a refresh to ensure that changes are shown if available + +x P2 need an event for adding roots to a subscriber to update the list shown + +x memory and sync set disposal in syncsetcompare input!!!! VERY IMPORTANT!!! + +- overiding outgoing/incoming doesn't show the changes in the commit dialog because the filter is only configured to show in one direction. + +====================================================================== + PR LIST (16-01-2004) +====================================================================== +x progress monitoring in SyncSet.reset and such. there are many places where null progress monitors are passed along. +- showing sync view in commit dialog is complicated because there is no easy way of finding out exactly which resources will be committed at the + point the commit comment dialog is shown. Need to provide new API on the commit dialog for this. +- convert details dialogs that show sync view into wizards, this allows more room to browse the changes. almost like the refactoring. Preview >> button instead of Next >>. +x job status handler API or not?? + +====================================================================== + PR LIST (26-01-2004) +====================================================================== +x navigable APIs must be consolidated, sync view navigation +x compare configuration review +x logical view extensions [not going to do this in 3.0] +x content provider should not assume diff nodes have associated resources + - content provider input? Is it a diff node or sync set? diff node hack required for getting the + compare editor input working. +x viewer input as a diffnode with a sync set seems wrong? +- share reconciling with existing (e.g. using compare contents to resolve) +x comment grouping logical view +- target migration + +====================================================================== + PR LIST (30-01-2004) MV +====================================================================== +x actions in sync view all assume that selection will have a resource (e.g refresh action). + - how would a refresh know what to select if a change comment node was selected, for example + - could first attempt to obtain resource and, if that fails, visit children to obtain resources + [jm] I think that actions will have to know about DiffNodes and we need the helper to + get the list of children nodes. + [jm] added Utils.getResources(Iselection) does all the logic for retreiving resources +x sorter is related to input so may need to change when input does + - there does not appear to be a clean way to change the sorter and input without causing two refreshes +x SyncInfoSet##getOutOfSyncDescendants(IResource) is speced to include the resource itself if it is out-of-sync + - this is a bit confusing as the name implies otherwise + - should either consider a name change or a spec change + [jm] I never understood why is was spec'd like that :) You can decide... +x compare input requires root node to have children or diff viewer is not added + - this is problematic when creating a wizard page that is dynamically populated + - not sure if there's problems caused by returning true when there are no children + [jm] I think this it's fine to have root nodes return true to hasChildren. I don't like + compares subtle way of determining is the diff viewer should be shown, but in our case a + root node can safely always have children. +x several places require a resource + - e.g. conflict propogation requires a resource but shouldn't (modified to work without a resource) + x conflicts do not propogate in comment view [jm] fixed + [jm] we have to change this assumption everywhere! Actions, label decorators... and such. + [jm] does sync info diff node require a resource? currently it does. But I still don't like + the SyncSet methods that take IResource.ROOT to return first level children. +x there are times when the sync set changes but the input hasn't yet and the given input + doesn't handle outgoing changes. For example, when changing from incoming to outgoing with + the change log root, the change log root gets a reset from the sync set then the input + is changed. this can cause an NPE. Must look into the ordering here. + [mv] I think we have to make the statement that the content provider must handle all sync types + in some fashion. I recall that we discussed the restriction that a sync diff root node must + show all elements in it's sync set. Could the comment builder place all outgoing changes in + an additional section. The user would never see this but it would fulfill the contract. + [jm] yes, this is what i ended up doing. + [mv] for efficiency, we should still try to couple the mode change with the content provider + change so that the diff node tree is not built and displayed twice during a change +- the test cases starve the subscriber event handler such that an event has additions and removals for the same resources + - this causes failures in the diff tree builders + - although less likely in UI, can still happen + - need tests for these scenarios to ensure generated event is correct after addition and removal +x there are several places in SyncInfoSet and in the DiffNodes where we must use the workspace root + as the input resource to imply get all members? Maybe this should be cleaned up a bit. +x SyncInfoSet must be cleaned up a lot, the API is vague and method names are not clear. + x we need a way to ensure that the sync set does not change while we are building a diff tree + x events are only fired from endInput(). It should work in both batching and non-batching mode +x SyncInfoDiffNode doesn't have to return a resource or a syncinfo. By definition a diff node already has API + for returning a sync kind getKind() and access to all three resources getRight(), getLeft(), getAncestor(). + +====================================================================== + PR LIST (02-02-2004) MV +====================================================================== +x sync view title says "Summary" when first opened +- would like to show subscriber roots as compressed folders at root of sync view + - sync set needs to have the concept of roots +x How is a reset propogated through the sync set chain. + - I'm concerned that this is adhoc at the moment. we need to make it explicit. +x why must clearModelObjects go deep? Can't you just disconnect from the parent? + +====================================================================== + PR LIST (05-02-2004) MV +====================================================================== +x I notice that SyncInfoDiffNode requires a resource (via assert) and sync info is only obtained from +SyncInfoDiffNodes (in Util). This is problematic as now the diff tree cannot contain diff nodes that +do not map to a resource but parent nodes that do. The selection determination for SubscriberAction +needs to walk the diff node tree for this case. + +====================================================================== + PR LIST (05-02-2004) Jm +====================================================================== +- cvs merge participant doesn't get view progress support because participant is added before +viewer is created. But this should be solvable by ensuring that showInActivePerspective forces +viewer creation in a sync exec. + +============================== +x initialize case doesn't work because main page is shown as empty but mode is correct +x how do we handle changes to sync: re-create new nodes or update the nodes with new sync kind? +x new projects don't show up? +- how does our APIs support moves/renames? Do we need another sync state? + +===== +x status line doesn't show? +- there's a bunch of non-NLSd strings? +- performance scalability with large sets +- initialization feedback when set is populating? +- scenarios/user doc + - most sync state stuff must be tested by automated tests + - progress should have scenarios (expected feedback, init case) + - errors +- resource filtering as seen in Refreshcompletedialog is very ineficient +- can you call start on the collector multiple times?
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/icons/full/ovr/warning_co.gif b/bundles/org.eclipse.team.ui/icons/full/ovr/warning_co.gif Binary files differnew file mode 100644 index 000000000..3af228cea --- /dev/null +++ b/bundles/org.eclipse.team.ui/icons/full/ovr/warning_co.gif diff --git a/bundles/org.eclipse.team.ui/plugin.properties b/bundles/org.eclipse.team.ui/plugin.properties index 56c08c388..cb76d2eca 100644 --- a/bundles/org.eclipse.team.ui/plugin.properties +++ b/bundles/org.eclipse.team.ui/plugin.properties @@ -13,14 +13,12 @@ pluginName=Team Support UI Team=Team configurationWizards=Configuration Wizards -targetWizards=Target Site Addition Wizards synchronizeParticipants=Synchronize View Participants +logicalViews=Logical Synchronize Views TeamPreferencePage.name=Team TextPreferencePage.name=File Content IgnorePreferencePage.name=Ignored Resources -loginDetails=Login Details -targetSite=Target Site ConfigureProject.label=&Share Project... ConfigureProject.tooltip=Share the project with others using a version and configuration management system. @@ -30,7 +28,6 @@ Team.viewCategory=Team Synchronizing.perspective=Team Synchronizing SyncView.name=Synchronize -OldSyncView.name=Old Synchronize ProjectSetImportWizard.name=Team Project Set ProjectSetImportWizard.description=A wizard that imports a Team Project Set @@ -57,3 +54,6 @@ Command.selectNextChange.description=Move to the next change Command.selectNextChange.name=Next Change Command.selectPreviousChange.description=Move to the previous change Command.selectPreviousChange.name=Previous Change + +CompressFolderView.name=Compress Folders +CompressFolderView.description=Compress in-sync folders paths diff --git a/bundles/org.eclipse.team.ui/plugin.xml b/bundles/org.eclipse.team.ui/plugin.xml index 61c69ed72..cc3c1521d 100644 --- a/bundles/org.eclipse.team.ui/plugin.xml +++ b/bundles/org.eclipse.team.ui/plugin.xml @@ -20,14 +20,18 @@ <import plugin="org.eclipse.ui.workbench.texteditor" optional="true"/> <import plugin="org.eclipse.ui.editors" optional="true"/> <import plugin="org.eclipse.core.resources"/> - <import plugin="org.eclipse.core.runtime.compatibility"/> + <import plugin="org.eclipse.core.runtime.compatibility" optional="true"/> <import plugin="org.eclipse.team.core"/> <import plugin="org.eclipse.ui"/> <import plugin="org.eclipse.compare"/> + <import plugin="org.eclipse.update.ui.forms"/> + <import plugin="org.eclipse.ui.forms"/> </requires> + <extension-point id="configurationWizards" name="%configurationWizards" schema="schema/configurationWizards.exsd"/> <extension-point id="synchronizeParticipants" name="%synchronizeParticipants" schema="schema/synchronizeParticipants.exsd"/> + <extension-point id="logicalViews" name="%logicalViews" schema="schema/logicalViews.exsd"/> <!-- **************** PREFERENCES ******************* --> <extension @@ -54,8 +58,8 @@ <extension point="org.eclipse.ui.popupMenus"> <objectContribution - objectClass="org.eclipse.core.resources.IResource" adaptable="true" + objectClass="org.eclipse.core.resources.IResource" id="org.eclipse.team.ui.ResourceContributions"> <menu label="%TeamGroupMenu.label" @@ -100,13 +104,13 @@ </menu> </objectContribution> <objectContribution - objectClass="org.eclipse.core.resources.IProject" adaptable="true" + objectClass="org.eclipse.core.resources.IProject" id="org.eclipse.team.ui.ProjectContributions"> <action label="%ConfigureProject.label" - tooltip="%ConfigureProject.tooltip" class="org.eclipse.team.internal.ui.actions.ConfigureProjectAction" + tooltip="%ConfigureProject.tooltip" menubarPath="team.main/projectGroup" enablesFor="1" id="org.eclipse.team.ui.ConfigureProject"> @@ -123,8 +127,8 @@ <view name="%SyncView.name" icon="icons/full/cview16/synch_synch.gif" - fastViewWidthRatio="0.25" category="org.eclipse.team.ui" + fastViewWidthRatio="0.25" class="org.eclipse.team.internal.ui.synchronize.SynchronizeView" id="org.eclipse.team.sync.views.SynchronizeView"> </view> @@ -134,7 +138,7 @@ point="org.eclipse.ui.perspectives"> <perspective name="%Synchronizing.perspective" - icon="icons/full/cview16/synch_synch.gif" + icon="icons/full/cview16/synch_synch.gif" class="org.eclipse.team.internal.ui.synchronize.TeamSynchronizingPerspective" id="org.eclipse.team.ui.TeamSynchronizingPerspective"> </perspective> @@ -144,9 +148,9 @@ <perspectiveExtension targetID="org.eclipse.ui.resourcePerspective"> <perspectiveShortcut - id="org.eclipse.team.ui.TeamSynchronizingPerspective"> + id="org.eclipse.team.ui.TeamSynchronizingPerspective"> </perspectiveShortcut> - </perspectiveExtension> + </perspectiveExtension> </extension> <!-- ****************** Import Wizards ********************* --> <extension @@ -207,17 +211,6 @@ description="%ActionSet.description" visible="false" id="org.eclipse.team.ui.actionSet"> -<!-- <action - definitionId="org.eclipse.team.ui.syncview.syncAll" - label="%Command.syncAll.name" - style="pulldown" - icon="icons/full/cview16/synch_synch.gif" - tooltip="%Command.syncAll.description" - class="org.eclipse.team.internal.ui.sync.actions.SyncAllAction" - toolbarPath="Normal/CVS" - id="org.eclipse.team.internal.ui.sync.actions.SyncAllAction"> - </action> - --> </actionSet> </extension> diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/IPreferenceIds.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/IPreferenceIds.java index 1f4bf8e28..38c613284 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/IPreferenceIds.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/IPreferenceIds.java @@ -14,18 +14,19 @@ public interface IPreferenceIds { public static final String PREFIX = TeamUIPlugin.ID + "."; //$NON-NLS-1$ // Sync Viewer - public static final String SYNCVIEW_BACKGROUND_SYNC = PREFIX + "background_sync"; //$NON-NLS-1$ - public static final String SYNCVIEW_SCHEDULED_SYNC = PREFIX + "scheduled_sync"; //$NON-NLS-1$ - public static final String SYNCVIEW_DELAY = PREFIX + "scheduled_sync_delay"; //$NON-NLS-1$ public static final String SYNCVIEW_COMPRESS_FOLDERS = PREFIX + "compress_folders"; //$NON-NLS-1$ public static final String SYNCVIEW_SELECTED_MODE = PREFIX + "syncview_selected_mode"; //$NON-NLS-1$ public static final String SYNCVIEW_DEFAULT_PERSPECTIVE = PREFIX + "syncview_default_perspective"; //$NON-NLS-1$ public static final String SYNCVIEW_DEFAULT_PERSPECTIVE_NONE = PREFIX + "sync_view_perspective_none"; //$NON-NLS-1$ - public static final String SYNCVIEW_VIEW_TYPE = PREFIX + "view_type"; //$NON-NLS-1$ - public static final String SYNCVIEW_VIEW_TABLESORT = PREFIX + "table_column_sort"; //$NON-NLS-1$ - public static final String SYNCVIEW_VIEW_TABLESORT_REVERSED = PREFIX + "table_column_sort_reversed"; //$NON-NLS-1$ - public static final String SYNCVIEW_VIEW_SYNCINFO_IN_LABEL = PREFIX + "view_syncinfo_in_label"; //$NON-NLS-1$ + + public static final String SYNCVIEW_VIEW_PROMPT_WHEN_NO_CHANGES = PREFIX + "syncview_promptwhennochanges"; //$NON-NLS-1$ + public static final String SYNCVIEW_VIEW_PROMPT_WITH_CHANGES = PREFIX + "syncview_promptwithchanges"; //$NON-NLS-1$ + + public static final String SYNCVIEW_VIEW_BKG_PROMPT_WHEN_NO_CHANGES = PREFIX + "syncview__bkg_promptwhennochanges"; //$NON-NLS-1$ + public static final String SYNCVIEW_VIEW_BKG_PROMPT_WITH_CHANGES = PREFIX + "syncview_bkg_promptwithchanges"; //$NON-NLS-1$ + + public static final String SYNCVIEW_VIEW_SMART_MODE_SWITCH = PREFIX + "syncview_smartmode"; //$NON-NLS-1$ } diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/NatureToPropertyAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/NatureToPropertyAction.java deleted file mode 100644 index c07f3f45c..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/NatureToPropertyAction.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.ui; - -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.team.core.RepositoryProvider; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.ui.actions.TeamAction; -import org.eclipse.ui.actions.WorkspaceModifyOperation; - -public class NatureToPropertyAction extends TeamAction { - - /** - * @see org.eclipse.team.internal.ui.actions.TeamAction#isEnabled() - */ - protected boolean isEnabled() throws TeamException { - return true; - } - - /** - * @see org.eclipse.ui.IActionDelegate#run(IAction) - */ - public void run(IAction action) { - run(new WorkspaceModifyOperation() { - public void execute(IProgressMonitor monitor) throws InterruptedException, InvocationTargetException { - try { - final Shell shell = getShell(); - IProject[] projects = getSelectedProjects(); - List statii = new ArrayList(); - for (int i = 0; i < projects.length; i++) { - IFile file = projects[i].getFile(".project"); //$NON-NLS-1$ - IStatus status = ResourcesPlugin.getWorkspace().validateEdit(new IFile[] {file}, shell); - if (status.getCode() == IStatus.OK) { - RepositoryProvider.convertNatureToProperty(projects[i], true); - } else { - statii.add(status); - RepositoryProvider.convertNatureToProperty(projects[i], false); - } - } - if (!statii.isEmpty()) { - final IStatus[] statusArray = (IStatus[])statii.toArray(new IStatus[statii.size()]); - shell.getDisplay().syncExec(new Runnable() { - public void run() { - if (statusArray.length == 1) { - ErrorDialog.openError(shell, Policy.bind("NatureToPropertyAction.label"), Policy.bind("NatureToPropertyAction.message"), statusArray[0]); //$NON-NLS-1$ //$NON-NLS-2$ - } else { - ErrorDialog.openError(shell, Policy.bind("NatureToPropertyAction.label"), Policy.bind("NatureToPropertyAction.message"), new MultiStatus(TeamUIPlugin.ID, 0, statusArray, Policy.bind("NatureToPropertyAction.multiMessage"), null)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - } - }); - for (int i = 0; i < statusArray.length; i++) { - TeamUIPlugin.log(statusArray[i]); - } - } - } catch (TeamException e) { - throw new InvocationTargetException(e); - } finally { - monitor.done(); - } - } - }, Policy.bind("NatureToPropertyAction.label"), PROGRESS_DIALOG); //$NON-NLS-1$ - } -} - diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/TeamAdapterFactory.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/TeamAdapterFactory.java new file mode 100644 index 000000000..315c9dcc1 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/TeamAdapterFactory.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * 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.ui; + +import org.eclipse.compare.structuremergeviewer.DiffNode; +import org.eclipse.core.runtime.IAdapterFactory; +import org.eclipse.team.internal.ui.synchronize.DiffNodeWorkbenchAdapter; +import org.eclipse.ui.model.IWorkbenchAdapter; + + +public class TeamAdapterFactory implements IAdapterFactory { + + private DiffNodeWorkbenchAdapter diffNodeAdapter = new DiffNodeWorkbenchAdapter(); + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class) + */ + public Object getAdapter(Object adaptableObject, Class adapterType) { + if(adaptableObject instanceof DiffNode && adapterType == IWorkbenchAdapter.class) { + return diffNodeAdapter; + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList() + */ + public Class[] getAdapterList() { + // TODO Auto-generated method stub + return new Class[] {IWorkbenchAdapter.class}; + } +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/TeamUIPlugin.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/TeamUIPlugin.java index 5ed19cfbc..5de10c18f 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/TeamUIPlugin.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/TeamUIPlugin.java @@ -14,17 +14,10 @@ package org.eclipse.team.internal.ui; import java.lang.reflect.InvocationTargetException; import java.net.MalformedURLException; import java.net.URL; -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; +import java.util.*; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtension; -import org.eclipse.core.runtime.IPluginDescriptor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; +import org.eclipse.compare.structuremergeviewer.DiffNode; +import org.eclipse.core.runtime.*; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.resource.ImageDescriptor; @@ -33,24 +26,19 @@ import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; -import org.eclipse.team.internal.ui.jobs.RefreshSubscriberInputJob; -import org.eclipse.team.internal.ui.jobs.RefreshSubscriberJob; -import org.eclipse.team.internal.ui.synchronize.views.SyncViewerTableSorter; import org.eclipse.team.internal.ui.synchronize.SynchronizeManager; import org.eclipse.team.internal.ui.synchronize.TeamSynchronizingPerspective; import org.eclipse.team.ui.ISharedImages; import org.eclipse.team.ui.TeamUI; -import org.eclipse.team.ui.synchronize.TeamSubscriberParticipant; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; +import org.eclipse.ui.*; import org.eclipse.ui.plugin.AbstractUIPlugin; /** * TeamUIPlugin is the plugin for generic, non-provider specific, * team UI functionality in the workbench. */ -public class TeamUIPlugin extends AbstractUIPlugin implements IPropertyChangeListener { +public class TeamUIPlugin extends AbstractUIPlugin { private static TeamUIPlugin instance; @@ -58,7 +46,6 @@ public class TeamUIPlugin extends AbstractUIPlugin implements IPropertyChangeLis public static final String ICON_PATH = "icons/full/"; //$NON-NLS-1$ public static final String ID = "org.eclipse.team.ui"; //$NON-NLS-1$ - public static final String PT_SUBSCRIBER_MENUS = "subscriberMenus"; //$NON-NLS-1$ // plugin id public static final String PLUGIN_ID = "org.eclipse.team.ui"; //$NON-NLS-1$ @@ -66,17 +53,7 @@ public class TeamUIPlugin extends AbstractUIPlugin implements IPropertyChangeLis private static List propertyChangeListeners = new ArrayList(5); private Hashtable imageDescriptors = new Hashtable(20); - private static List disposeOnShutdownImages= new ArrayList(); - private RefreshSubscriberInputJob refreshJob; - - /** - * Returns the job that refreshes the active subscribers in the background. - */ - public RefreshSubscriberInputJob getRefreshJob() { - return refreshJob; - } - /** * Creates a new TeamUIPlugin. * @@ -160,15 +137,15 @@ public class TeamUIPlugin extends AbstractUIPlugin implements IPropertyChangeLis */ protected void initializePreferences() { IPreferenceStore store = getPreferenceStore(); - store.setDefault(IPreferenceIds.SYNCVIEW_BACKGROUND_SYNC, true); - store.setDefault(IPreferenceIds.SYNCVIEW_SCHEDULED_SYNC, false); store.setDefault(IPreferenceIds.SYNCVIEW_VIEW_SYNCINFO_IN_LABEL, false); - store.setDefault(IPreferenceIds.SYNCVIEW_DELAY, 60 /* minutes */); store.setDefault(IPreferenceIds.SYNCVIEW_COMPRESS_FOLDERS, true); - store.setDefault(IPreferenceIds.SYNCVIEW_VIEW_TABLESORT, SyncViewerTableSorter.COL_NAME); - store.setDefault(IPreferenceIds.SYNCVIEW_VIEW_TABLESORT_REVERSED, false); - store.setDefault(IPreferenceIds.SYNCVIEW_SELECTED_MODE, TeamSubscriberParticipant.BOTH_MODE); + store.setDefault(IPreferenceIds.SYNCVIEW_SELECTED_MODE, SubscriberParticipant.BOTH_MODE); store.setDefault(IPreferenceIds.SYNCVIEW_DEFAULT_PERSPECTIVE, TeamSynchronizingPerspective.ID); + store.setDefault(IPreferenceIds.SYNCVIEW_VIEW_PROMPT_WHEN_NO_CHANGES, true); + store.setDefault(IPreferenceIds.SYNCVIEW_VIEW_PROMPT_WITH_CHANGES, true); + store.setDefault(IPreferenceIds.SYNCVIEW_VIEW_BKG_PROMPT_WHEN_NO_CHANGES, false); + store.setDefault(IPreferenceIds.SYNCVIEW_VIEW_BKG_PROMPT_WITH_CHANGES, true); + store.setDefault(IPreferenceIds.SYNCVIEW_VIEW_SMART_MODE_SWITCH, false); } /** @@ -202,18 +179,9 @@ public class TeamUIPlugin extends AbstractUIPlugin implements IPropertyChangeLis */ public void startup() throws CoreException { Policy.localize("org.eclipse.team.internal.ui.messages"); //$NON-NLS-1$ - initializePreferences(); - - getPreferenceStore().addPropertyChangeListener(this); - - // startup auto-refresh job if necessary - refreshJob = new RefreshSubscriberInputJob(Policy.bind("ScheduledSyncViewRefresh.taskName")); //$NON-NLS-1$ - refreshJob.setRefreshInterval(getPreferenceStore().getInt(IPreferenceIds.SYNCVIEW_DELAY) * 60); - if(getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_SCHEDULED_SYNC)) { - refreshJob.setRestartOnCancel(true); - refreshJob.setReschedule(true); - refreshJob.schedule(refreshJob.getScheduleDelay()); - } + initializePreferences(); + IAdapterFactory factory = new TeamAdapterFactory(); + Platform.getAdapterManager().registerAdapters(factory, DiffNode.class); ((SynchronizeManager)TeamUI.getSynchronizeManager()).init(); } @@ -222,7 +190,6 @@ public class TeamUIPlugin extends AbstractUIPlugin implements IPropertyChangeLis */ public void shutdown() throws CoreException { super.shutdown(); - disposeImages(); ((SynchronizeManager)TeamUI.getSynchronizeManager()).dispose(); } @@ -249,16 +216,6 @@ public class TeamUIPlugin extends AbstractUIPlugin implements IPropertyChangeLis listener.propertyChange(event); } } - - /** - * Registers the given image for being disposed when this plug-in is shutdown. - * - * @param image the image to register for disposal - */ - public static void disposeOnShutdown(Image image) { - if (image != null) - disposeOnShutdownImages.add(image); - } /** * Creates an image and places it in the image registry. @@ -279,6 +236,7 @@ public class TeamUIPlugin extends AbstractUIPlugin implements IPropertyChangeLis ImageDescriptor desc = ImageDescriptor.createFromURL(url); imageDescriptors.put(id, desc); } + /** * Returns the image descriptor for the given image ID. * Returns null if there is no such image. @@ -297,6 +255,7 @@ public class TeamUIPlugin extends AbstractUIPlugin implements IPropertyChangeLis } return (ImageDescriptor)imageDescriptors.get(id); } + /** * Convenience method to get an image descriptor for an extension * @@ -382,26 +341,8 @@ public class TeamUIPlugin extends AbstractUIPlugin implements IPropertyChangeLis createImageDescriptor(plugin, ISharedImages.IMG_PROJECTSET_EXPORT_BANNER, baseURL); // Live Sync View icons - createImageDescriptor(plugin, ISharedImages.IMG_COMPRESSED_FOLDER, baseURL); - } - - /** - * Dispose of images - */ - public static void disposeImages() { - // Delegate to the plugin instance to avoid concurrent class loading problems - getPlugin().privateDisposeImages(); - } - private void privateDisposeImages() { - if (disposeOnShutdownImages != null) { - Iterator i= disposeOnShutdownImages.iterator(); - while (i.hasNext()) { - Image img= (Image) i.next(); - if (!img.isDisposed()) - img.dispose(); - } - imageDescriptors= null; - } + createImageDescriptor(plugin, ISharedImages.IMG_COMPRESSED_FOLDER, baseURL); + createImageDescriptor(plugin, ISharedImages.IMG_WARNING, baseURL); } /** @@ -417,6 +358,16 @@ public class TeamUIPlugin extends AbstractUIPlugin implements IPropertyChangeLis return display; } + public Image getImage(String key) { + Image image = getImageRegistry().get(key); + if(image == null) { + ImageDescriptor d = getImageDescriptor(key); + image = d.createImage(); + getImageRegistry().put(key, image); + } + return image; + } + public static void run(IRunnableWithProgress runnable) { try { PlatformUI.getWorkbench().getActiveWorkbenchWindow().run(true, true, runnable); @@ -425,29 +376,5 @@ public class TeamUIPlugin extends AbstractUIPlugin implements IPropertyChangeLis } catch (InterruptedException e2) { // Nothing to be done } - } - - public void propertyChange(PropertyChangeEvent event) { - // update the background sync delay - if(event.getProperty().equals(IPreferenceIds.SYNCVIEW_DELAY)) { - RefreshSubscriberJob refreshJob = getRefreshJob(); - refreshJob.setRefreshInterval(getPreferenceStore().getInt(IPreferenceIds.SYNCVIEW_DELAY) * 60); - } - - // enable / disable the background sync job - if(event.getProperty().equals(IPreferenceIds.SYNCVIEW_SCHEDULED_SYNC)) { - RefreshSubscriberJob refreshJob = getRefreshJob(); - refreshJob.setRefreshInterval(getPreferenceStore().getInt(IPreferenceIds.SYNCVIEW_DELAY) * 60); - boolean value = getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_SCHEDULED_SYNC); - if(value) { - refreshJob.setRestartOnCancel(true); - refreshJob.setReschedule(true); - refreshJob.schedule(refreshJob.getRefreshInterval() * 1000); - } else { - refreshJob.setRestartOnCancel(false /* don't restart the job */); - refreshJob.setReschedule(false); - refreshJob.cancel(); - } - } - } + } } diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/Utils.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/Utils.java index c16308606..de47eea72 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/Utils.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/Utils.java @@ -11,43 +11,53 @@ package org.eclipse.team.internal.ui; import java.lang.reflect.InvocationTargetException; -import java.util.ResourceBundle; +import java.util.*; +import java.util.List; +import org.eclipse.compare.CompareConfiguration; +import org.eclipse.compare.structuremergeviewer.IDiffContainer; +import org.eclipse.compare.structuremergeviewer.IDiffElement; +import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.*; import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.*; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.custom.BusyIndicator; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.*; import org.eclipse.team.core.TeamException; +import org.eclipse.team.core.synchronize.IResourceVariant; +import org.eclipse.team.core.synchronize.SyncInfo; import org.eclipse.team.ui.TeamImages; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; +import org.eclipse.team.ui.synchronize.viewers.SynchronizeModelElement; +import org.eclipse.ui.*; public class Utils { /** - * The SortOperation takes a collection of objects and returns - * a sorted collection of these objects. Concrete instances of this - * class provide the criteria for the sorting of the objects based on - * the type of the objects. + * The SortOperation takes a collection of objects and returns a sorted + * collection of these objects. Concrete instances of this class provide + * the criteria for the sorting of the objects based on the type of the + * objects. */ static public abstract class Sorter { + /** - * Returns true is elementTwo is 'greater than' elementOne - * This is the 'ordering' method of the sort operation. - * Each subclass overides this method with the particular - * implementation of the 'greater than' concept for the - * objects being sorted. + * Returns true is elementTwo is 'greater than' elementOne This is the + * 'ordering' method of the sort operation. Each subclass overides this + * method with the particular implementation of the 'greater than' + * concept for the objects being sorted. */ public abstract boolean compare(Object elementOne, Object elementTwo); + /** * Sort the objects in sorted collection and return that collection. */ private Object[] quickSort(Object[] sortedCollection, int left, int right) { int originalLeft = left; int originalRight = right; - Object mid = sortedCollection[ (left + right) / 2]; + Object mid = sortedCollection[(left + right) / 2]; do { while (compare(sortedCollection[left], mid)) left++; @@ -67,29 +77,32 @@ public class Utils { sortedCollection = quickSort(sortedCollection, left, originalRight); return sortedCollection; } + /** - * Return a new sorted collection from this unsorted collection. - * Sort using quick sort. + * Return a new sorted collection from this unsorted collection. Sort + * using quick sort. */ public Object[] sort(Object[] unSortedCollection) { int size = unSortedCollection.length; Object[] sortedCollection = new Object[size]; - //copy the array so can return a new sorted collection + //copy the array so can return a new sorted collection System.arraycopy(unSortedCollection, 0, sortedCollection, 0, size); if (size > 1) quickSort(sortedCollection, 0, size - 1); return sortedCollection; } } - - + /** * Shows the given errors to the user. - * - * @param Exception the exception containing the error - * @param title the title of the error dialog - * @param message the message for the error dialog - * @param shell the shell to open the error dialog in + * @param Exception + * the exception containing the error + * @param title + * the title of the error dialog + * @param message + * the message for the error dialog + * @param shell + * the shell to open the error dialog in */ public static void handleError(Shell shell, Exception exception, String title, String message) { IStatus status = null; @@ -97,17 +110,17 @@ public class Utils { boolean dialog = false; Throwable t = exception; if (exception instanceof TeamException) { - status = ((TeamException)exception).getStatus(); + status = ((TeamException) exception).getStatus(); log = false; dialog = true; } else if (exception instanceof InvocationTargetException) { - t = ((InvocationTargetException)exception).getTargetException(); + t = ((InvocationTargetException) exception).getTargetException(); if (t instanceof TeamException) { - status = ((TeamException)t).getStatus(); + status = ((TeamException) t).getStatus(); log = false; dialog = true; } else if (t instanceof CoreException) { - status = ((CoreException)t).getStatus(); + status = ((CoreException) t).getStatus(); log = true; dialog = true; } else if (t instanceof InterruptedException) { @@ -118,7 +131,8 @@ public class Utils { dialog = true; } } - if (status == null) return; + if (status == null) + return; if (!status.isOK()) { IStatus toShow = status; if (status.isMultiStatus()) { @@ -141,8 +155,8 @@ public class Utils { } } } - public static void runWithProgress(Shell parent, boolean cancelable, - final IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException { + + public static void runWithProgress(Shell parent, boolean cancelable, final IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException { boolean createdShell = false; try { if (parent == null || parent.isDisposed()) { @@ -162,6 +176,7 @@ public class Utils { // pop up progress dialog after a short delay final Exception[] holder = new Exception[1]; BusyIndicator.showWhile(parent.getDisplay(), new Runnable() { + public void run() { try { runnable.run(new NullProgressMonitor()); @@ -179,47 +194,48 @@ public class Utils { throw (InterruptedException) holder[0]; } } - //new TimeoutProgressMonitorDialog(parent, TIMEOUT).run(true /*fork*/, cancelable, runnable); + //new TimeoutProgressMonitorDialog(parent, TIMEOUT).run(true + // /*fork*/, cancelable, runnable); } finally { - if (createdShell) parent.dispose(); + if (createdShell) + parent.dispose(); } } + /** * Creates a progress monitor and runs the specified runnable. - * - * @param parent the parent Shell for the dialog - * @param cancelable if true, the dialog will support cancelation - * @param runnable the runnable - * - * @exception InvocationTargetException when an exception is thrown from the runnable - * @exception InterruptedException when the progress monitor is cancelled + * @param parent + * the parent Shell for the dialog + * @param cancelable + * if true, the dialog will support cancelation + * @param runnable + * the runnable + * @exception InvocationTargetException + * when an exception is thrown from the runnable + * @exception InterruptedException + * when the progress monitor is cancelled */ - public static void runWithProgressDialog(Shell parent, boolean cancelable, - final IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException { - + public static void runWithProgressDialog(Shell parent, boolean cancelable, final IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException { new ProgressMonitorDialog(parent).run(cancelable, cancelable, runnable); } + /* * This method is only for use by the Target Management feature (see bug - * 16509). - * - * @param t + * 16509). @param t */ public static void handle(Throwable t) { IStatus error = null; if (t instanceof InvocationTargetException) { - t = ((InvocationTargetException)t).getTargetException(); + t = ((InvocationTargetException) t).getTargetException(); } if (t instanceof CoreException) { - error = ((CoreException)t).getStatus(); + error = ((CoreException) t).getStatus(); } else if (t instanceof TeamException) { - error = ((TeamException)t).getStatus(); + error = ((TeamException) t).getStatus(); } else { error = new Status(IStatus.ERROR, TeamUIPlugin.ID, 1, Policy.bind("simpleInternal"), t); //$NON-NLS-1$ } - Shell shell = new Shell(Display.getDefault()); - if (error.getSeverity() == IStatus.INFO) { MessageDialog.openInformation(shell, Policy.bind("information"), error.getMessage()); //$NON-NLS-1$ } else { @@ -231,64 +247,196 @@ public class Utils { TeamUIPlugin.log(error.getSeverity(), error.getMessage(), t); } } - + + public static IWorkbenchPartSite findSite(Control c) { + while (c != null && !c.isDisposed()) { + Object data = c.getData(); + if (data instanceof IWorkbenchPart) + return ((IWorkbenchPart) data).getSite(); + c = c.getParent(); + } + return null; + } + + public static IWorkbenchPartSite findSite() { + IWorkbench workbench = TeamUIPlugin.getPlugin().getWorkbench(); + IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); + if (window != null) { + IWorkbenchPage page = window.getActivePage(); + if (page != null) { + IWorkbenchPart part = page.getActivePart(); + if (part != null) + return part.getSite(); + } + } + return null; + } + public static void initAction(IAction a, String prefix) { Utils.initAction(a, prefix, Policy.bundle); } + + public static void updateLabels(SyncInfo sync, CompareConfiguration config) { + final IResourceVariant remote = sync.getRemote(); + final IResourceVariant base = sync.getBase(); + String localContentId = sync.getLocalContentIdentifier(); + if (localContentId != null) { + config.setLeftLabel(Policy.bind("SyncInfoCompareInput.localLabelExists", localContentId)); //$NON-NLS-1$ + } else { + config.setLeftLabel(Policy.bind("SyncInfoCompareInput.localLabel")); //$NON-NLS-1$ + } + if (remote != null) { + config.setRightLabel(Policy.bind("SyncInfoCompareInput.remoteLabelExists", remote.getContentIdentifier())); //$NON-NLS-1$ + } else { + config.setRightLabel(Policy.bind("SyncInfoCompareInput.remoteLabel")); //$NON-NLS-1$ + } + if (base != null) { + config.setAncestorLabel(Policy.bind("SyncInfoCompareInput.baseLabelExists", base.getContentIdentifier())); //$NON-NLS-1$ + } else { + config.setAncestorLabel(Policy.bind("SyncInfoCompareInput.baseLabel")); //$NON-NLS-1$ + } + } + /** * Initialize the given Action from a ResourceBundle. */ public static void initAction(IAction a, String prefix, ResourceBundle bundle) { - - String labelKey= "label"; //$NON-NLS-1$ - String tooltipKey= "tooltip"; //$NON-NLS-1$ - String imageKey= "image"; //$NON-NLS-1$ - String descriptionKey= "description"; //$NON-NLS-1$ - + String labelKey = "label"; //$NON-NLS-1$ + String tooltipKey = "tooltip"; //$NON-NLS-1$ + String imageKey = "image"; //$NON-NLS-1$ + String descriptionKey = "description"; //$NON-NLS-1$ if (prefix != null && prefix.length() > 0) { - labelKey= prefix + labelKey; - tooltipKey= prefix + tooltipKey; - imageKey= prefix + imageKey; - descriptionKey= prefix + descriptionKey; + labelKey = prefix + labelKey; + tooltipKey = prefix + tooltipKey; + imageKey = prefix + imageKey; + descriptionKey = prefix + descriptionKey; } - String s = Policy.bind(labelKey, bundle); - if(s != null) + if (s != null) a.setText(s); s = Policy.bind(tooltipKey, bundle); - if(s != null) + if (s != null) a.setToolTipText(s); s = Policy.bind(descriptionKey, bundle); - if(s != null) + if (s != null) a.setDescription(s); - - String relPath= Policy.bind(imageKey, bundle); - if (relPath != null && ! relPath.equals(imageKey) && relPath.trim().length() > 0) { - + String relPath = Policy.bind(imageKey, bundle); + if (relPath != null && !relPath.equals(imageKey) && relPath.trim().length() > 0) { String cPath; String dPath; String ePath; - if (relPath.indexOf("/") >= 0) { //$NON-NLS-1$ - String path= relPath.substring(1); - cPath= 'c' + path; - dPath= 'd' + path; - ePath= 'e' + path; + String path = relPath.substring(1); + cPath = 'c' + path; + dPath = 'd' + path; + ePath = 'e' + path; } else { - cPath= "clcl16/" + relPath; //$NON-NLS-1$ - dPath= "dlcl16/" + relPath; //$NON-NLS-1$ - ePath= "elcl16/" + relPath; //$NON-NLS-1$ + cPath = "clcl16/" + relPath; //$NON-NLS-1$ + dPath = "dlcl16/" + relPath; //$NON-NLS-1$ + ePath = "elcl16/" + relPath; //$NON-NLS-1$ } - - ImageDescriptor id= TeamImages.getImageDescriptor(dPath); // we set the disabled image first (see PR 1GDDE87) + ImageDescriptor id = TeamImages.getImageDescriptor(dPath); // we + // set + // the + // disabled + // image + // first + // (see + // PR + // 1GDDE87) if (id != null) a.setDisabledImageDescriptor(id); - id= TeamUIPlugin.getImageDescriptor(cPath); + id = TeamUIPlugin.getImageDescriptor(cPath); if (id != null) a.setHoverImageDescriptor(id); - id= TeamUIPlugin.getImageDescriptor(ePath); + id = TeamUIPlugin.getImageDescriptor(ePath); if (id != null) a.setImageDescriptor(id); } } -} + + public static String modeToString(int mode) { + switch (mode) { + case SubscriberParticipant.INCOMING_MODE : + return Policy.bind("Utils.22"); //$NON-NLS-1$ + case SubscriberParticipant.OUTGOING_MODE : + return Policy.bind("Utils.23"); //$NON-NLS-1$ + case SubscriberParticipant.BOTH_MODE : + return Policy.bind("Utils.24"); //$NON-NLS-1$ + case SubscriberParticipant.CONFLICTING_MODE : + return Policy.bind("Utils.25"); //$NON-NLS-1$ + } + return Policy.bind("Utils.26"); //$NON-NLS-1$ + } + + public static String workingSetToString(IWorkingSet set, int maxLength) { + String text = Policy.bind("StatisticsPanel.noWorkingSet"); //$NON-NLS-1$ + if (set != null) { + text = set.getName(); + if (text.length() > maxLength) { + text = text.substring(0, maxLength - 3) + "..."; //$NON-NLS-1$ + } + } + return text; + } + + /** + * Returns the list of resources contained in the given elements. + * @param elements + * @return the list of resources contained in the given elements. + */ + public static IResource[] getResources(Object[] elements) { + List resources = new ArrayList(); + for (int i = 0; i < elements.length; i++) { + Object element = elements[i]; + IResource resource = null; + if (element instanceof IResource) { + resource = (IResource)element; + } else if (element instanceof SynchronizeModelElement){ + resource = ((SynchronizeModelElement) element).getResource(); + } else { + resource = (IResource)getAdapter(element, IResource.class); + } + if (resource != null) { + resources.add(resource); + } + } + return (IResource[]) resources.toArray(new IResource[resources.size()]); + } + + public static Object getAdapter(Object element, Class adapter) { + if (element instanceof IAdaptable) { + return ((IAdaptable) element).getAdapter(adapter); + } + return null; + } + + /** + * This method returns all out-of-sync SyncInfos that are in the current + * selection. + * + * @return the list of selected sync infos + */ + public static IDiffElement[] getDiffNodes(Object[] selected) { + Set result = new HashSet(); + for (int i = 0; i < selected.length; i++) { + Object object = selected[i]; + if(object instanceof IDiffElement) { + collectAllNodes((IDiffElement)object, result); + } + } + return (IDiffElement[]) result.toArray(new IDiffElement[result.size()]); + } + + private static void collectAllNodes(IDiffElement element, Set nodes) { + if(element.getKind() != SyncInfo.IN_SYNC) { + nodes.add(element); + } + if(element instanceof IDiffContainer) { + IDiffElement[] children = ((IDiffContainer)element).getChildren(); + for (int i = 0; i < children.length; i++) { + collectAllNodes(children[i], nodes); + } + } + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/ConfigureProjectAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/ConfigureProjectAction.java index 4a5c56ef2..2ec58ed3b 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/ConfigureProjectAction.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/ConfigureProjectAction.java @@ -17,7 +17,10 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.action.IAction; import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.wizard.IWizard; import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Shell; import org.eclipse.team.core.RepositoryProvider; import org.eclipse.team.internal.ui.Policy; import org.eclipse.team.internal.ui.wizards.ConfigureProjectWizard; @@ -28,6 +31,13 @@ import org.eclipse.team.internal.ui.wizards.ConfigureProjectWizard; * configuration that is necessary. */ public class ConfigureProjectAction extends TeamAction { + private static class ResizeWizardDialog extends WizardDialog { + public ResizeWizardDialog(Shell parentShell, IWizard newWizard) { + super(parentShell, newWizard); + setShellStyle(getShellStyle() | SWT.RESIZE); + } + } + /* * Method declared on IActionDelegate. */ @@ -38,7 +48,8 @@ public class ConfigureProjectAction extends TeamAction { IProject project = getSelectedProjects()[0]; ConfigureProjectWizard wizard = new ConfigureProjectWizard(); wizard.init(null, project); - WizardDialog dialog = new WizardDialog(getShell(), wizard); + WizardDialog dialog = new ResizeWizardDialog(getShell(), wizard); + //dialog. dialog.open(); } catch (Exception e) { throw new InvocationTargetException(e); diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ICVSRunnableContext.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/ITeamRunnableContext.java index 64adcea1c..36218fc9a 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ICVSRunnableContext.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/ITeamRunnableContext.java @@ -8,7 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.team.internal.ccvs.ui.operations; +package org.eclipse.team.internal.ui.actions; import java.lang.reflect.InvocationTargetException; @@ -17,13 +17,13 @@ import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.swt.widgets.Shell; /** - * An ICVSRunnableContext is used to provide the context for a CVS operation. + * An ITeamRunnableContext is used to provide the context for a Team operation. * The hierarchy of contexts is used to configure the following: * 1) whether the operation is run in the background as a job * 2) whether the operation modifies the workspace * 3) what shell the operation should use to display info to the user */ -public interface ICVSRunnableContext { +public interface ITeamRunnableContext { /** * Run the given runnable in the context of the receiver. By default, the diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSNonblockingRunnableContext.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/JobRunnableContext.java index dc8ee0e79..bca21a756 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSNonblockingRunnableContext.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/JobRunnableContext.java @@ -8,45 +8,42 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.team.internal.ccvs.ui.operations; +package org.eclipse.team.internal.ui.actions; import java.lang.reflect.InvocationTargetException; import org.eclipse.core.resources.WorkspaceJob; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.IJobChangeListener; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.jobs.*; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; -import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; +import org.eclipse.team.core.TeamException; +import org.eclipse.ui.*; +import org.eclipse.ui.progress.IWorkbenchSiteProgressService; /** * This runnable context executes it's operation in the context of a background job. */ -public class CVSNonblockingRunnableContext implements ICVSRunnableContext { +public class JobRunnableContext implements ITeamRunnableContext { private IJobChangeListener listener; + private IWorkbenchSite site; - public CVSNonblockingRunnableContext() { - this(null); + public JobRunnableContext() { + this(null, null); } - public CVSNonblockingRunnableContext(IJobChangeListener listener) { + public JobRunnableContext(IJobChangeListener listener, IWorkbenchSite site) { this.listener = listener; + this.site = site; } protected IStatus run(IRunnableWithProgress runnable, IProgressMonitor monitor) { try { runnable.run(monitor); } catch (InvocationTargetException e) { - return CVSException.wrapException(e).getStatus(); + return TeamException.asTeamException(e).getStatus(); } catch (InterruptedException e) { return Status.OK_STATUS; } @@ -56,7 +53,7 @@ public class CVSNonblockingRunnableContext implements ICVSRunnableContext { protected Job getBasicJob(String title, final IRunnableWithProgress runnable) { return new Job(title) { public IStatus run(IProgressMonitor monitor) { - return CVSNonblockingRunnableContext.this.run(runnable, monitor); + return JobRunnableContext.this.run(runnable, monitor); } }; } @@ -64,13 +61,13 @@ public class CVSNonblockingRunnableContext implements ICVSRunnableContext { protected Job getWorkspaceJob(String title, final IRunnableWithProgress runnable) { return new WorkspaceJob(title) { public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { - return CVSNonblockingRunnableContext.this.run(runnable, monitor); + return JobRunnableContext.this.run(runnable, monitor); } }; } /* (non-Javadoc) - * @see org.eclipse.team.internal.ccvs.ui.operations.ICVSRunnableContext#run(java.lang.String, boolean, org.eclipse.jface.operation.IRunnableWithProgress) + * @see org.eclipse.team.internal.ccvs.ui.operations.ITeamRunnableContext#run(java.lang.String, boolean, org.eclipse.jface.operation.IRunnableWithProgress) */ public void run(String title, ISchedulingRule schedulingRule, boolean postponeBuild, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException { Job job; @@ -85,15 +82,22 @@ public class CVSNonblockingRunnableContext implements ICVSRunnableContext { if (listener != null) { job.addJobChangeListener(listener); } - schedule(job); + schedule(job, site); } - protected void schedule(Job job) { + private void schedule(Job job, IWorkbenchSite site) { + if (site != null) { + IWorkbenchSiteProgressService siteProgress = (IWorkbenchSiteProgressService) site.getAdapter(IWorkbenchSiteProgressService.class); + if (siteProgress != null) { + siteProgress.schedule(job); + return; + } + } job.schedule(); } /* (non-Javadoc) - * @see org.eclipse.team.internal.ccvs.ui.operations.ICVSRunnableContext#getShell() + * @see org.eclipse.team.internal.ccvs.ui.operations.ITeamRunnableContext#getShell() */ public Shell getShell() { final Shell[] newShell = new Shell[] { null }; diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSBlockingRunnableContext.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/ProgressDialogRunnableContext.java index a36b164df..8ad5daffc 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSBlockingRunnableContext.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/ProgressDialogRunnableContext.java @@ -8,7 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.team.internal.ccvs.ui.operations; +package org.eclipse.team.internal.ui.actions; import java.lang.reflect.InvocationTargetException; @@ -20,7 +20,7 @@ import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.jface.operation.IRunnableContext; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.swt.widgets.Shell; -import org.eclipse.team.internal.ccvs.ui.Policy; +import org.eclipse.team.internal.ui.Policy; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.progress.IProgressService; @@ -28,12 +28,12 @@ import org.eclipse.ui.progress.IProgressService; * This CVS runnable context blocks the UI and can therfore have a shell assigned to * it (since the shell won't be closed by the user before the runnable completes. */ -public class CVSBlockingRunnableContext implements ICVSRunnableContext { +public class ProgressDialogRunnableContext implements ITeamRunnableContext { private Shell shell; private IRunnableContext runnableContext; - public CVSBlockingRunnableContext(Shell shell) { + public ProgressDialogRunnableContext(Shell shell) { this.shell = shell; } diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/SubscriberAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/SubscriberAction.java new file mode 100644 index 000000000..4ebb5d37d --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/SubscriberAction.java @@ -0,0 +1,319 @@ +/******************************************************************************* + * 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.ui.actions; + +import java.lang.reflect.InvocationTargetException; +import java.util.*; + +import org.eclipse.compare.structuremergeviewer.IDiffElement; +import org.eclipse.core.resources.*; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.jobs.*; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.internal.core.TeamPlugin; +import org.eclipse.team.internal.ui.TeamUIPlugin; +import org.eclipse.team.internal.ui.Utils; +import org.eclipse.team.ui.synchronize.viewers.SynchronizeModelElement; +import org.eclipse.team.ui.synchronize.viewers.SyncInfoModelElement; +import org.eclipse.ui.*; + +/** + * This action provides utilities for performing operations on selections that + * contain instances of {@link SyncInfoModelElement}. Subclasses can use this support + * to: + * <ul> + * <li>provides easy filtering of selection + * <li>provides scheduling action via workbench part (provide feedback via view) + * <li>provides support for running action in background or foreground + * <li>provides support for locking workspace resources + * </ul> + * @see SyncInfo + * @see SyncInfoSet + * @see SyncInfoModelElement + * @since 3.0 + */ +public abstract class SubscriberAction implements IObjectActionDelegate, IViewActionDelegate { + + private IStructuredSelection selection; + private IWorkbenchPart part; + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + public final void run(IAction action) { + // TODO: We used to prompt for unsaved changes in any editor. We don't anymore. Would + // it be better to prompt for unsaved changes to editors affected by this action? + SyncInfoSet syncSet = makeSyncInfoSetFromSelection(getFilteredSyncInfos()); + if (syncSet == null || syncSet.isEmpty()) return; + try { + getRunnableContext().run(getJobName(syncSet), getSchedulingRule(syncSet), true, getRunnable(syncSet)); + } catch (InvocationTargetException e) { + handle(e); + } catch (InterruptedException e) { + handle(e); + } + } + + /** + * Subsclasses must override to provide behavior for the action. + * @param syncSet the set of filtered sync info objects on which to perform the action. + * @param monitor a progress monitor, or <code>null</code> if progress + * reporting and cancellation are not desired + * @throws TeamException if something went wrong running the action + */ + protected abstract void run(SyncInfoSet syncSet, IProgressMonitor monitor) throws TeamException; + + /** + * Subsclasses may override to perform custom processing on the selection before + * the action is run. This can be used to prompt the user for more information. + * @param infos the + */ + protected SyncInfoSet makeSyncInfoSetFromSelection(SyncInfo[] infos) { + return new SyncInfoSet(infos); + } + + protected void handle(Exception e) { + Utils.handle(e); + } + + /** + * This method returns all instances of SyncInfo that are in the current + * selection. For a tree view, this is any descendants of the selected resource that are + * contained in the view. + * + * @return the selected resources + */ + protected IDiffElement[] getDiffElements() { + return Utils.getDiffNodes(((IStructuredSelection)selection).toArray()); + } + + /** + * The default enablement behavior for subscriber actions is to enable + * the action if there is at least one SyncInfo in the selection + * for which the action is enabled (determined by invoking + * <code>isEnabled(SyncInfo)</code>). + * @see org.eclipse.team.internal.ui.actions.TeamAction#isEnabled() + */ + protected boolean isEnabled() throws TeamException { + return (getFilteredDiffElements().length > 0); + } + + /** + * Default filter includes all out-of-sync elements in the current + * selection. + * @return a sync info filter which selects all out-of-sync resources. + */ + protected FastSyncInfoFilter getSyncInfoFilter() { + return new FastSyncInfoFilter(); + } + + /** + * Return the selected diff element for which this action is enabled. + * @return the list of selected diff elements for which this action is enabled. + */ + protected IDiffElement[] getFilteredDiffElements() { + IDiffElement[] elements = getDiffElements(); + List filtered = new ArrayList(); + for (int i = 0; i < elements.length; i++) { + IDiffElement e = elements[i]; + if (e instanceof SyncInfoModelElement) { + SyncInfo info = ((SyncInfoModelElement) e).getSyncInfo(); + if (info != null && getSyncInfoFilter().select(info)) { + filtered.add(e); + } + } + } + return (IDiffElement[]) filtered.toArray(new IDiffElement[filtered.size()]); + } + + /** + * Return the selected SyncInfo for which this action is enabled. + * @return the selected SyncInfo for which this action is enabled. + */ + protected SyncInfo[] getFilteredSyncInfos() { + IDiffElement[] elements = getFilteredDiffElements(); + List filtered = new ArrayList(); + for (int i = 0; i < elements.length; i++) { + IDiffElement e = elements[i]; + if (e instanceof SyncInfoModelElement) { + filtered.add(((SyncInfoModelElement)e).getSyncInfo()); + } + } + return (SyncInfo[]) filtered.toArray(new SyncInfo[filtered.size()]); + } + + private void markBusy(IDiffElement[] elements, boolean isBusy) { + for (int i = 0; i < elements.length; i++) { + IDiffElement element = elements[i]; + if (element instanceof SynchronizeModelElement) { + ((SynchronizeModelElement)element).setPropertyToRoot(SynchronizeModelElement.BUSY_PROPERTY, isBusy); + } + } + } + + /** + * Uses the {@link #canRunAsJob()} hint to return a {@link ITeamRunnableContext}. + * + * @return the runnable context in which to run this action. + */ + protected ITeamRunnableContext getRunnableContext() { + if (canRunAsJob()) { + // mark resources that will be affected by job + final IDiffElement[] affectedElements = getFilteredDiffElements(); + markBusy(affectedElements, true); + + // register to unmark when job is finished + IJobChangeListener listener = new JobChangeAdapter() { + public void done(IJobChangeEvent event) { + markBusy(affectedElements, false); + } + }; + return new JobRunnableContext(listener, getSite()); + } else { + return new ProgressDialogRunnableContext(getShell()); + } + } + + /** + * If this action can safely be run in the background, then subclasses can + * override this method and return <code>true</code>. This will make their + * action run in a {@link Job}. + * + * @return <code>true</code> if this action can be run in the background and + * <code>false</code> otherwise. + */ + protected boolean canRunAsJob() { + return false; + } + + /** + * Return the job name to be used if the action can run as a job. + * + * @param syncSet + * @return + */ + protected String getJobName(SyncInfoSet syncSet) { + return ""; //$NON-NLS-1$ + } + + /** + * Return a scheduling rule that includes all resources that will be operated + * on by the subscriber action. The default behavior is to include all projects + * effected by the operation. Subclasses may override. + * + * @param syncSet + * @return + */ + protected ISchedulingRule getSchedulingRule(SyncInfoSet syncSet) { + IResource[] resources = syncSet.getResources(); + Set set = new HashSet(); + for (int i = 0; i < resources.length; i++) { + IResource resource = resources[i]; + set.add(resource.getProject()); + } + IProject[] projects = (IProject[]) set.toArray(new IProject[set.size()]); + if (projects.length == 1) { + return projects[0]; + } else { + return new MultiRule(projects); + } + } + + protected IRunnableWithProgress getRunnable(final SyncInfoSet syncSet) { + return new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + try { + SubscriberAction.this.run(syncSet, monitor); + } catch (TeamException e) { + throw new InvocationTargetException(e); + } + } + }; + } + + private IWorkbenchSite getSite() { + IWorkbenchSite site = null; + if(part != null) { + site = part.getSite(); + } + return site; + } + + + /* (non-Javadoc) + * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart) + */ + public void setActivePart(IAction action, IWorkbenchPart targetPart) { + this.part = targetPart; + } + + + /* (non-Javadoc) + * @see org.eclipse.ui.IViewActionDelegate#init(org.eclipse.ui.IViewPart) + */ + public void init(IViewPart view) { + this.part = view; + } + + /* + * Method declared on IActionDelegate. + */ + public void selectionChanged(IAction action, ISelection selection) { + if (selection instanceof IStructuredSelection) { + this.selection = (IStructuredSelection) selection; + if (action != null) { + setActionEnablement(action); + } + } + } + + /** + * Method invoked from <code>selectionChanged(IAction, ISelection)</code> + * to set the enablement status of the action. The instance variable + * <code>selection</code> will contain the latest selection so the methods + * <code>getSelectedResources()</code> and <code>getSelectedProjects()</code> + * will provide the proper objects. + * + * This method can be overridden by subclasses but should not be invoked by them. + */ + protected void setActionEnablement(IAction action) { + try { + action.setEnabled(isEnabled()); + } catch (TeamException e) { + if (e.getStatus().getCode() == IResourceStatus.OUT_OF_SYNC_LOCAL) { + // Enable the action to allow the user to discover the problem + action.setEnabled(true); + } else { + action.setEnabled(false); + // We should not open a dialog when determining menu enablements so log it instead + TeamPlugin.log(e); + } + } + } + + protected Shell getShell() { + if(part != null) { + return part.getSite().getShell(); + } else { + IWorkbench workbench = TeamUIPlugin.getPlugin().getWorkbench(); + if (workbench == null) return null; + IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); + if (window == null) return null; + return window.getShell(); + } + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/TeamAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/TeamAction.java index af26e305c..706fe6d96 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/TeamAction.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/TeamAction.java @@ -265,8 +265,10 @@ public abstract class TeamAction extends ActionDelegate implements IObjectAction * Method declared on IObjectActionDelegate. */ public void setActivePart(IAction action, IWorkbenchPart targetPart) { - this.shell = targetPart.getSite().getShell(); - this.targetPart = targetPart; + if(targetPart != null) { + this.shell = targetPart.getSite().getShell(); + this.targetPart = targetPart; + } } /** * Shows the given errors to the user. diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/DetailsDialog.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/DetailsDialog.java index 44ab6a890..53069ba25 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/DetailsDialog.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/DetailsDialog.java @@ -18,11 +18,7 @@ import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.*; /** * A simple superclass for detail button dialogs. @@ -117,10 +113,20 @@ abstract public class DetailsDialog extends Dialog { if (includeCancelButton()) { createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); } - detailsButton = createButton(parent, IDialogConstants.DETAILS_ID, IDialogConstants.SHOW_DETAILS_LABEL, false); + if(includeDetailsButton()) { + detailsButton = createButton(parent, IDialogConstants.DETAILS_ID, getDetailsButtonLabelShow(), false); + } updateEnablements(); } + protected String getDetailsButtonLabelShow() { + return IDialogConstants.SHOW_DETAILS_LABEL; + } + + protected String getDetailsButtonLabelHide() { + return IDialogConstants.HIDE_DETAILS_LABEL; + } + /* (non-Javadoc) * Method declared on Dialog. * Creates and returns the contents of the upper part @@ -150,7 +156,7 @@ abstract public class DetailsDialog extends Dialog { label.setImage(image); label.setLayoutData(new GridData( GridData.HORIZONTAL_ALIGN_CENTER | - GridData.VERTICAL_ALIGN_CENTER)); + GridData.VERTICAL_ALIGN_BEGINNING)); // add a composite to the right to contain the custom components Composite right = new Composite(top, SWT.NONE); @@ -166,11 +172,13 @@ abstract public class DetailsDialog extends Dialog { createMainDialogArea(composite); } - errorMessageLabel = new Label(composite, SWT.NONE); - errorMessageLabel.setLayoutData(new GridData( - GridData.GRAB_HORIZONTAL | - GridData.HORIZONTAL_ALIGN_FILL)); - errorMessageLabel.setForeground(getShell().getDisplay().getSystemColor(SWT.COLOR_RED)); + if(includeErrorMessage()) { + errorMessageLabel = new Label(composite, SWT.NONE); + errorMessageLabel.setLayoutData(new GridData( + GridData.GRAB_HORIZONTAL | + GridData.HORIZONTAL_ALIGN_FILL)); + errorMessageLabel.setForeground(getShell().getDisplay().getSystemColor(SWT.COLOR_RED)); + } Dialog.applyDialogFont(parent); return composite; @@ -202,11 +210,11 @@ abstract public class DetailsDialog extends Dialog { if (detailsCreated) { detailsComposite.dispose(); detailsCreated = false; - detailsButton.setText(IDialogConstants.SHOW_DETAILS_LABEL); + detailsButton.setText(getDetailsButtonLabelShow()); } else { detailsComposite = createDropDownDialogArea((Composite)getContents()); detailsCreated = true; - detailsButton.setText(IDialogConstants.HIDE_DETAILS_LABEL); + detailsButton.setText(getDetailsButtonLabelHide()); } Dialog.applyDialogFont(getContents()); Point newSize = getContents().computeSize(SWT.DEFAULT, SWT.DEFAULT); @@ -287,4 +295,12 @@ abstract public class DetailsDialog extends Dialog { protected boolean isDetailsVisible() { return detailsCreated; } + + protected boolean includeErrorMessage() { + return true; + } + + protected boolean includeDetailsButton() { + return true; + } } diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/DialogArea.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/DialogArea.java index 0e428747c..035f8a3cb 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/DialogArea.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/DialogArea.java @@ -197,6 +197,8 @@ public abstract class DialogArea { // GridLayout GridLayout layout = new GridLayout(); layout.numColumns = numColumns; + layout.marginHeight = 0; + layout.marginWidth = 0; composite.setLayout(layout); // GridData diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/PreferencePageContainerDialog.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/PreferencePageContainerDialog.java index b67505869..acaf2b035 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/PreferencePageContainerDialog.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/PreferencePageContainerDialog.java @@ -250,7 +250,7 @@ public class PreferencePageContainerDialog extends Dialog implements IPreference gd = new GridData(); gd.horizontalAlignment = GridData.END; fTitleImage.setLayoutData(gd); - + updateMessage(); return fTitleArea; } diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/IJobListener.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/IJobListener.java deleted file mode 100644 index e09cf6d52..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/IJobListener.java +++ /dev/null @@ -1,26 +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.ui.jobs; - -import org.eclipse.core.runtime.QualifiedName; - -/** - * This interface allows interested parties to receive notification - * when work has started or stopped for a given job type. The <code>started</code> - * method is invoked when the first job is started for the given <code>jobType</code>. - * The <code>finish</code> method is called when the last job of a given type stops. - * Several jobs for the job type may start and stop in the interum without causing - * notification to the listener. - */ -public interface IJobListener { - public void started(QualifiedName jobType); - public void finished(QualifiedName jobType); -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/JobBusyCursor.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/JobBusyCursor.java index 4c807b58e..f29974b31 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/JobBusyCursor.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/JobBusyCursor.java @@ -10,27 +10,21 @@ *******************************************************************************/ package org.eclipse.team.internal.ui.jobs; -import org.eclipse.core.runtime.QualifiedName; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Cursor; import org.eclipse.swt.widgets.*; /** - * This class will show a busy cursor over a control when jobs of a particular type - * are running. + * This is temporary until the UI adds support for this directly into views. + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=51991 */ -public class JobBusyCursor implements IJobListener { +public class JobBusyCursor { private Composite composite; private Cursor waitCursor; - private QualifiedName jobType; - public JobBusyCursor(Composite composite, QualifiedName jobType) { + public JobBusyCursor(Composite composite) { this.composite = composite; - this.jobType = jobType; - synchronized (this) { - JobStatusHandler.addJobListener(this, jobType); - } } private Cursor getWaitCursor() { @@ -73,30 +67,16 @@ public class JobBusyCursor implements IJobListener { if (waitCursor != null) { waitCursor.dispose(); } - JobStatusHandler.removeJobListener(this, jobType); - } - - private void showBusyCursor() { - showCursor(getWaitCursor()); } - /* (non-Javadoc) - * @see org.eclipse.team.internal.ui.jobs.IJobListener#started(org.eclipse.core.runtime.QualifiedName) - */ - public void started(QualifiedName jobType) { - showBusyCursor(); + public void started() { + showCursor(getWaitCursor()); } - /* (non-Javadoc) - * @see org.eclipse.team.internal.ui.jobs.IJobListener#finished(org.eclipse.core.runtime.QualifiedName) - */ - public void finished(QualifiedName jobType) { + public void finished() { showCursor(null); } - /** - * @return Returns the control. - */ public Composite getComposite() { return composite; } diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/JobStatusHandler.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/JobStatusHandler.java deleted file mode 100644 index c6c1da64a..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/JobStatusHandler.java +++ /dev/null @@ -1,232 +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.ui.jobs; - -import java.util.*; - -import org.eclipse.core.runtime.*; -import org.eclipse.core.runtime.jobs.*; - -/** - * This class is reponsible for notifying listeners when jobs registered - * with the handler start and stop. Start is invoked when the first registered job starts - * anf finish is invoked when the last registered job finishes. - */ -public class JobStatusHandler extends JobChangeAdapter { - - private static Map handlers = new HashMap(); - - private QualifiedName jobType; - private Set jobs = new HashSet(); - private List listeners = new ArrayList(); - - /* - * Private class used to safely notify listeners of job type starts and - * finishes. Subclass override the notify(IJobListener) method to - * fire specific events inside an ISafeRunnable. - */ - private abstract class Notification implements ISafeRunnable { - private IJobListener listener; - public void handleException(Throwable exception) { - // don't log the exception....it is already being logged in Platform#run - } - public void run(IJobListener listener) { - this.listener = listener; - Platform.run(this); - } - public void run() throws Exception { - notify(listener); - } - /** - * Subsclasses overide this method to send an event safely to a lsistener - * @param listener - */ - protected abstract void notify(IJobListener listener); - } - - /** - * Associate the job with the given jobType and schedule the job for - * immediate start. - * @param job - * @param jobType - */ - public static void schedule(Job job, QualifiedName jobType) { - JobStatusHandler handler; - synchronized (handlers) { - handler = getHandler(jobType); - if (handler == null) { - handler = createHandler(jobType); - } - } - handler.schedule(job); - } - - /** - * Add a listener for the given job type. - * @param listener - * @param jobType - */ - public static void addJobListener(IJobListener listener, QualifiedName jobType) { - synchronized (handlers) { - JobStatusHandler handler = getHandler(jobType); - if (handler == null) { - handler = createHandler(jobType); - } - handler.addJobListener(listener); - } - } - - /** - * Remove a previously registered listener for the given job type. - * @param listener - * @param jobType - */ - public static void removeJobListener(IJobListener listener, QualifiedName jobType) { - synchronized (handlers) { - JobStatusHandler handler = getHandler(jobType); - if (handler != null) { - handler.removeJobListener(listener); - } - } - } - - /** - * Return whether a job of the given type is currently running. - * @param jobType - * @return - */ - public static boolean hasRunningJobs(QualifiedName jobType) { - JobStatusHandler handler = getHandler(jobType); - if (handler != null) { - return handler.hasRunningJobs(); - } - return false; - } - - private static JobStatusHandler getHandler(QualifiedName jobType) { - return (JobStatusHandler)handlers.get(jobType); - } - - private static JobStatusHandler createHandler(QualifiedName jobType) { - JobStatusHandler existing = getHandler(jobType); - if (existing != null) return existing; - JobStatusHandler newHandler = new JobStatusHandler(jobType); - handlers.put(jobType, newHandler); - return newHandler; - } - - protected JobStatusHandler(QualifiedName jobType) { - super(); - this.jobType = jobType; - } - - public void schedule(Job job) { - job.addJobChangeListener(this); - job.schedule(); - } - - public void done(IJobChangeEvent event) { - jobDone(event.getJob()); - - } - - public void addJobListener(IJobListener listener) { - synchronized (listeners) { - listeners.add(listener); - } - } - public void removeJobListener(IJobListener listener) { - synchronized (listeners) { - listeners.remove(listener); - } - } - - private void fireNotification(Notification notification) { - // Get a snapshot of the listeners so the list doesn't change while we're firing - IJobListener[] listenerArray; - synchronized (listeners) { - listenerArray = (IJobListener[]) listeners.toArray(new IJobListener[listeners.size()]); - } - // Notify each listener in a safe manner (i.e. so their exceptions don't kill us) - for (int i = 0; i < listenerArray.length; i++) { - IJobListener listener = listenerArray[i]; - notification.run(listener); - } - } - - private void jobStarted(Job job) { - if (recordJob(job)) { - fireStartNotification(); - } - } - - /* - * Record the job and return true if it's the first job of that type - */ - private boolean recordJob(Job job) { - if (!jobs.add(job)) { - // The job was already in the set. - return false; - } - return jobs.size() == 1; - } - - /* - * Remove the job and return true if it is the last job for the type - */ - private boolean removeJob(Job job) { - if (!jobs.remove(job)) { - // The job wasn't in the list. - return false; - } - return jobs.isEmpty(); - } - - private void fireStartNotification() { - fireNotification(new Notification() { - public void notify(IJobListener listener) { - listener.started(getJobType()); - } - }); - } - - private void jobDone(Job job) { - if (removeJob(job)) { - fireEndNotification(); - } - } - - private void fireEndNotification() { - fireNotification(new Notification() { - public void notify(IJobListener listener) { - listener.finished(getJobType()); - } - }); - } - - public boolean hasRunningJobs() { - return !jobs.isEmpty(); - } - - /** - * @return Returns the jobType. - */ - public QualifiedName getJobType() { - return jobType; - } - - /* (non-Javadoc) - * @see org.eclipse.core.runtime.jobs.IJobChangeListener#aboutToRun(org.eclipse.core.runtime.jobs.IJobChangeEvent) - */ - public void aboutToRun(IJobChangeEvent event) { - jobStarted(event.getJob()); - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/RefreshChangeListener.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/RefreshChangeListener.java new file mode 100644 index 000000000..d5a3d1723 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/RefreshChangeListener.java @@ -0,0 +1,55 @@ +package org.eclipse.team.internal.ui.jobs; + +import java.util.*; + +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.team.core.subscribers.*; +import org.eclipse.team.core.synchronize.*; + +class RefreshChangeListener implements ISubscriberChangeListener { + private List changes = new ArrayList(); + private SubscriberSyncInfoCollector collector; + + RefreshChangeListener(SubscriberSyncInfoCollector collector) { + this.collector = collector; + } + public void subscriberResourceChanged(ISubscriberChangeEvent[] deltas) { + for (int i = 0; i < deltas.length; i++) { + ISubscriberChangeEvent delta = deltas[i]; + if (delta.getFlags() == ISubscriberChangeEvent.SYNC_CHANGED) { + changes.add(delta); + } + } + } + public SyncInfo[] getChanges() { + collector.waitForCollector(new NullProgressMonitor()); + List changedSyncInfos = new ArrayList(); + SyncInfoSet set = collector.getSubscriberSyncInfoSet(); + for (Iterator it = changes.iterator(); it.hasNext();) { + ISubscriberChangeEvent delta = (ISubscriberChangeEvent) it.next(); + SyncInfo info = set.getSyncInfo(delta.getResource()); + if (info != null && interestingChange(info)) { + changedSyncInfos.add(info); + } + } + return (SyncInfo[]) changedSyncInfos.toArray(new SyncInfo[changedSyncInfos.size()]); + } + + private boolean interestingChange(SyncInfo info) { + int kind = info.getKind(); + if(isThreeWay()) { + int direction = SyncInfo.getDirection(kind); + return (direction == SyncInfo.INCOMING || direction == SyncInfo.CONFLICTING); + } else { + return SyncInfo.getChange(kind) != SyncInfo.IN_SYNC; + } + } + + private boolean isThreeWay() { + return collector.getSubscriber().getResourceComparator().isThreeWay(); + } + + public void clear() { + changes.clear(); + } +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/RefreshSubscriberInputJob.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/RefreshSubscriberInputJob.java deleted file mode 100644 index 72733971f..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/RefreshSubscriberInputJob.java +++ /dev/null @@ -1,115 +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.ui.jobs; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.TeamSubscriber; -import org.eclipse.team.internal.ui.Policy; -import org.eclipse.team.internal.ui.TeamUIPlugin; -import org.eclipse.team.internal.ui.synchronize.sets.SubscriberInput; - -/** - * Job that refreshes a registered list of subscriber inputs. Each input - * will have it's associated subscriber refreshed. - * - * There can be several refresh jobs created but they will be serialized. - */ -public class RefreshSubscriberInputJob extends RefreshSubscriberJob { - private List inputs = new ArrayList(3); - - public RefreshSubscriberInputJob(String name) { - super(name, null, null); - } - - public synchronized void addSubscriberInput(SubscriberInput input) { - stop(); - inputs.add(input); - start(); - } - - public synchronized void removeSubscriberInput(SubscriberInput input) { - stop(); - inputs.remove(input); - start(); - } - - private void stop() { - int state = getState(); - if(state == Job.RUNNING) { - cancel(); - try { - join(); - } catch (InterruptedException e) { - // continue - } - } - } - - /** - * This is run by the job scheduler. A list of subscribers will be refreshed, errors will not stop the job - * and it will continue to refresh the other subscribers. - */ - public IStatus runInWorkspace(IProgressMonitor monitor) { - // Synchronized to ensure only one refresh job is running at a particular time - synchronized (getFamily()) { - MultiStatus status = new MultiStatus(TeamUIPlugin.ID, TeamException.UNABLE, Policy.bind("RefreshSubscriberJob.0"), null); //$NON-NLS-1$ - - // if there are no inputs to refresh, just return - if(inputs.isEmpty()) { - return Status.OK_STATUS; - } - - try { - // Only allow one refresh job at a time - // NOTE: It would be cleaner if this was done by a scheduling - // rule but at the time of writting, it is not possible due to - // the scheduling rule containment rules. - lastTimeRun = System.currentTimeMillis(); - if(monitor.isCanceled()) { - return Status.CANCEL_STATUS; - } - try { - for (Iterator it = inputs.iterator(); it.hasNext();) { - SubscriberInput input = (SubscriberInput) it.next(); - monitor.setTaskName(Policy.bind(Policy.bind("RefreshSubscriberInputJob.1"), input.getParticipant().getName(), new Integer(input.workingSetRoots().length).toString())); //$NON-NLS-1$ - TeamSubscriber subscriber = input.getSubscriber(); - subscriber.refresh(input.workingSetRoots(), IResource.DEPTH_INFINITE, Policy.subMonitorFor(monitor, 100)); - } - } catch(TeamException e) { - status.merge(e.getStatus()); - } - } catch(OperationCanceledException e2) { - return Status.CANCEL_STATUS; - } finally { - monitor.done(); - } - return status.isOK() ? Status.OK_STATUS : (IStatus) status; - } - } - - /* (non-Javadoc) - * @see org.eclipse.core.runtime.jobs.Job#shouldRun() - */ - public boolean shouldRun() { - return ! inputs.isEmpty(); - } -}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/RefreshSubscriberJob.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/RefreshSubscriberJob.java index aff6f88c9..439cc04f8 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/RefreshSubscriberJob.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/RefreshSubscriberJob.java @@ -10,20 +10,20 @@ *******************************************************************************/ package org.eclipse.team.internal.ui.jobs; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.WorkspaceJob; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.IJobChangeEvent; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.core.runtime.jobs.JobChangeAdapter; +import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.jobs.*; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.TeamSubscriber; +import org.eclipse.team.core.subscribers.*; +import org.eclipse.team.core.synchronize.*; import org.eclipse.team.internal.ui.Policy; import org.eclipse.team.internal.ui.TeamUIPlugin; +import org.eclipse.team.internal.ui.synchronize.IRefreshEvent; +import org.eclipse.team.internal.ui.synchronize.IRefreshSubscriberListener; /** * Job to refresh a subscriber with its remote state. @@ -48,32 +48,129 @@ public class RefreshSubscriberJob extends WorkspaceJob { /** * If true a rescheduled refresh job should be retarted when cancelled */ - /* internal use only */ boolean restartOnCancel = true; + private boolean restartOnCancel = true; /** * The schedule delay used when rescheduling a completed job */ - /* internal use only */ static long scheduleDelay = 20000; - - /** - * Time the job was run last in milliseconds. - */ - protected long lastTimeRun = 0; + private static long scheduleDelay; /** * The subscribers and roots to refresh. If these are changed when the job * is running the job is cancelled. */ private IResource[] resources; - private TeamSubscriber subscriber; + private SubscriberSyncInfoCollector collector; - public RefreshSubscriberJob(String name, IResource[] resources, TeamSubscriber subscriber) { - super(name); + /** + * Refresh started/completed listener for every refresh + */ + private static List listeners = new ArrayList(1); + + protected static class RefreshEvent implements IRefreshEvent { + int type; + Subscriber subscriber; + SyncInfo[] changes; + long startTime = 0; + long stopTime = 0; + IStatus status; + IResource[] resources; + RefreshEvent(int type, IResource[] resources, Subscriber subscriber) { + this.type = type; + this.subscriber = subscriber; + this.resources = resources; + } + + public int getRefreshType() { + return type; + } + + public Subscriber getSubscriber() { + return subscriber; + } + + public SyncInfo[] getChanges() { + return changes; + } + + public void setChanges(SyncInfo[] changes) { + this.changes = changes; + } + + /** + * @return Returns the startTime. + */ + public long getStartTime() { + return startTime; + } + + /** + * @param startTime The startTime to set. + */ + public void setStartTime(long startTime) { + this.startTime = startTime; + } + + /** + * @return Returns the stopTime. + */ + public long getStopTime() { + return stopTime; + } + + /** + * @param stopTime The stopTime to set. + */ + public void setStopTime(long stopTime) { + this.stopTime = stopTime; + } + + public IStatus getStatus() { + return status; + } + + public void setStatus(IStatus status) { + this.status = status; + } + + public IResource[] getResources() { + return resources; + } + } + + private abstract class Notification implements ISafeRunnable { + private IRefreshSubscriberListener listener; + public void handleException(Throwable exception) { + // don't log the exception....it is already being logged in Platform#run + } + public void run(IRefreshSubscriberListener listener) { + this.listener = listener; + Platform.run(this); + } + public void run() throws Exception { + notify(listener); + } + /** + * Subsclasses overide this method to send an event safely to a lsistener + * @param listener + */ + protected abstract void notify(IRefreshSubscriberListener listener); + } + + + public RefreshSubscriberJob(String name, IResource[] resources, SubscriberSyncInfoCollector collector) { + this(name, collector); this.resources = resources; - this.subscriber = subscriber; + } + + public RefreshSubscriberJob(String name, SubscriberSyncInfoCollector collector) { + super(name); + + this.collector = collector; setPriority(Job.DECORATE); + setRefreshInterval(3600 /* 1 hour */); addJobChangeListener(new JobChangeAdapter() { public void done(IJobChangeEvent event) { @@ -85,11 +182,11 @@ public class RefreshSubscriberJob extends WorkspaceJob { restartOnCancel = true; } } - }); + }); } public boolean shouldRun() { - return getSubscriber() != null; + return collector != null && getSubscriber() != null; } public boolean belongsTo(Object family) { @@ -108,7 +205,7 @@ public class RefreshSubscriberJob extends WorkspaceJob { // Synchronized to ensure only one refresh job is running at a particular time synchronized (getFamily()) { MultiStatus status = new MultiStatus(TeamUIPlugin.ID, TeamException.UNABLE, Policy.bind("RefreshSubscriberJob.0"), null); //$NON-NLS-1$ - TeamSubscriber subscriber = getSubscriber(); + Subscriber subscriber = getSubscriber(); IResource[] roots = getResources(); // if there are no resources to refresh, just return @@ -117,17 +214,25 @@ public class RefreshSubscriberJob extends WorkspaceJob { } monitor.beginTask(null, 100); + RefreshEvent event = new RefreshEvent(reschedule ? IRefreshEvent.SCHEDULED_REFRESH : IRefreshEvent.USER_REFRESH, roots, collector.getSubscriber()); + RefreshChangeListener changeListener = new RefreshChangeListener(collector); try { // Only allow one refresh job at a time // NOTE: It would be cleaner if this was done by a scheduling // rule but at the time of writting, it is not possible due to // the scheduling rule containment rules. - lastTimeRun = System.currentTimeMillis(); + event.setStartTime(System.currentTimeMillis()); if(monitor.isCanceled()) { return Status.CANCEL_STATUS; } - try { - subscriber.refresh(roots, IResource.DEPTH_INFINITE, Policy.subMonitorFor(monitor, 100)); + try { + // Set-up change listener so that we can determine the changes found + // during this refresh. + subscriber.addListener(changeListener); + // Pre-Notify + notifyListeners(true, event); + // Perform the refresh + subscriber.refresh(roots, IResource.DEPTH_INFINITE, Policy.subMonitorFor(monitor, 100)); } catch(TeamException e) { status.merge(e.getStatus()); } @@ -136,16 +241,28 @@ public class RefreshSubscriberJob extends WorkspaceJob { } finally { monitor.done(); } - return status.isOK() ? Status.OK_STATUS : (IStatus) status; + + // Post-Notify + event.setChanges(changeListener.getChanges()); + event.setStopTime(System.currentTimeMillis()); + event.setStatus(status.isOK() ? Status.OK_STATUS : (IStatus) status); + notifyListeners(false, event); + changeListener.clear(); + + return event.getStatus(); } } protected IResource[] getResources() { - return resources; + if(resources != null) { + return resources; + } else { + return collector.getSubscriber().roots(); + } } - protected TeamSubscriber getSubscriber() { - return subscriber; + protected Subscriber getSubscriber() { + return collector.getSubscriber(); } public long getScheduleDelay() { @@ -196,7 +313,39 @@ public class RefreshSubscriberJob extends WorkspaceJob { return reschedule; } - public long getLastTimeRun() { - return lastTimeRun; + public static void addRefreshListener(IRefreshSubscriberListener listener) { + synchronized(listeners) { + if(! listeners.contains(listener)) { + listeners.add(listener); + } + } + } + + public static void removeRefreshListener(IRefreshSubscriberListener listener) { + synchronized(listeners) { + listeners.remove(listener); + } + } + + protected void notifyListeners(final boolean started, final IRefreshEvent event) { + // Get a snapshot of the listeners so the list doesn't change while we're firing + IRefreshSubscriberListener[] listenerArray; + synchronized (listeners) { + listenerArray = (IRefreshSubscriberListener[]) listeners.toArray(new IRefreshSubscriberListener[listeners.size()]); + } + // Notify each listener in a safe manner (i.e. so their exceptions don't kill us) + for (int i = 0; i < listenerArray.length; i++) { + IRefreshSubscriberListener listener = listenerArray[i]; + Notification notification = new Notification() { + protected void notify(IRefreshSubscriberListener listener) { + if(started) { + listener.refreshStarted(event); + } else { + listener.refreshDone(event); + } + } + }; + notification.run(listener); + } } }
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/RefreshUserNotificationPolicy.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/RefreshUserNotificationPolicy.java new file mode 100644 index 000000000..469146ecb --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/RefreshUserNotificationPolicy.java @@ -0,0 +1,95 @@ +package org.eclipse.team.internal.ui.jobs; + +import org.eclipse.core.runtime.*; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.team.core.synchronize.SyncInfo; +import org.eclipse.team.internal.ui.IPreferenceIds; +import org.eclipse.team.internal.ui.TeamUIPlugin; +import org.eclipse.team.internal.ui.synchronize.*; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.progress.UIJob; +import org.eclipse.team.internal.ui.Policy; + +public class RefreshUserNotificationPolicy implements IRefreshSubscriberListener { + + private SubscriberParticipant participant; + + public RefreshUserNotificationPolicy(SubscriberParticipant participant) { + this.participant = participant; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.team.internal.ui.jobs.IRefreshSubscriberListener#refreshStarted(org.eclipse.team.internal.ui.jobs.IRefreshEvent) + */ + public void refreshStarted(IRefreshEvent event) { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.team.internal.ui.jobs.IRefreshSubscriberListener#refreshDone(org.eclipse.team.internal.ui.jobs.IRefreshEvent) + */ + public void refreshDone(IRefreshEvent event) { + if(event.getSubscriber() != participant.getSubscriberSyncInfoCollector().getSubscriber()) return; + + int type = event.getRefreshType(); + + boolean promptWithChanges = TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_PROMPT_WITH_CHANGES); + boolean promptWhenNoChanges = TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_PROMPT_WHEN_NO_CHANGES); + boolean promptWithChangesBkg = TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_BKG_PROMPT_WITH_CHANGES); + boolean promptWhenNoChangesBkg = TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_BKG_PROMPT_WHEN_NO_CHANGES); + + boolean shouldPrompt = false; + SyncInfo[] infos = event.getChanges(); + + if (type == IRefreshEvent.USER_REFRESH) { + if (promptWhenNoChanges && infos.length == 0) { + shouldPrompt = true; + } else if (promptWithChanges && infos.length > 0) { + shouldPrompt = true; + } + } else { + if (promptWhenNoChangesBkg && infos.length == 0) { + shouldPrompt = true; + } else if (promptWithChangesBkg && infos.length > 0) { + shouldPrompt = true; + } + } + + // If there are interesting changes, ensure the sync view is showing them + if(infos.length > 0) { + participant.setMode(SubscriberParticipant.INCOMING_MODE); + } + + // Prompt user if preferences are set for this type of refresh. + if (shouldPrompt) { + notifyIfNeededModal(event); + } + RefreshSubscriberJob.removeRefreshListener(this); + } + + private void notifyIfNeededModal(final IRefreshEvent event) { + TeamUIPlugin.getStandardDisplay().asyncExec(new Runnable() { + public void run() { + RefreshCompleteDialog d = new RefreshCompleteDialog(new Shell(TeamUIPlugin.getStandardDisplay()), event, participant); + d.setBlockOnOpen(false); + d.open(); + } + }); + } + + private void notifyIfNeededNonModal(final IRefreshEvent event) { + String message = Policy.bind("RefreshUserNotificationPolicy.0", event.getSubscriber().getName()); //$NON-NLS-1$ + PlatformUI.getWorkbench().getProgressService().requestInUI(new UIJob(message) { + public IStatus runInUIThread(IProgressMonitor monitor) { + RefreshCompleteDialog d = new RefreshCompleteDialog(new Shell(TeamUIPlugin.getStandardDisplay()), event, participant); + d.setBlockOnOpen(false); + d.open(); + return Status.OK_STATUS; + } + }, message); + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/messages.properties b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/messages.properties index b0962d2e4..d524745b0 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/messages.properties +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/messages.properties @@ -12,16 +12,6 @@ # Message catalog for org.eclipse.team.ui ############################################### -AuthenticatedTargetSitePropertiesPage.Server=Server hostname: -AuthenticatedTargetSitePropertiesPage.User=&User: -AuthenticatedTargetSitePropertiesPage.Password=&Password: -AuthenticatedTargetSitePropertiesPage.Error=Error Occurred - -ProjectTargetMappingPropertiesPage.Error=A Bad Thing (tm) happened. -ProjectTargetMappingPropertiesPage.URL=Target site URL: -ProjectTargetMappingPropertiesPage.FolderName=Deployment path: -ProjectTargetMappingPropertiesPage.ChangeBtn=&Change these settings... - CatchupReleaseViewer.open=&Show Content Comparison CatchupReleaseViewer.expand=&Expand All CatchupReleaseViewer.ignoreWhiteSpace=&Ignore White Space @@ -100,16 +90,13 @@ LiveSyncView.titleTooltip=Working Set: {0} LiveSyncView.title=Synchronize LiveSyncView.titleSubscriber=Synchronize - {0} -SubscriberEventHandler.jobName=Updating synchronization states in the Synchronize view. -SubscriberEventHandler.errors=Errors have occured while calculating the synchronization state. The Synchronize View may be out-of-date. Refresh the view or fix the errors and re-run the Synchronize command. - SyncInfoCompareInput.localLabel=Local File SyncInfoCompareInput.localLabelExists=Local File ({0}) SyncInfoCompareInput.remoteLabel=Remote File SyncInfoCompareInput.baseLabel=Common Ancestor SyncInfoCompareInput.remoteLabelExists=Remote File ({0}) SyncInfoCompareInput.baseLabelExists=Common Ancestor ({0}) -SyncInfoCompareInput.title={0}: {1} +SyncInfoCompareInput.title={0} SyncInfoCompareInput.tooltip=Comparing resources from {0}: {1} TeamAction.internal=Internal error occurred. @@ -137,7 +124,7 @@ SynchronizationViewPreference.defaultPerspectiveDescription=This setting control SynchronizationViewPreference.defaultPerspectiveLabel=Perspective: ScheduledSyncViewRefresh.taskName=Refreshing synchronize view partners with remote -SyncViewRefresh.taskName=Refreshing ''{0}'' with remote +SyncViewRefresh.taskName=Refreshing ''{0}'' ExportProjectSetMainPage.Select_the_projects_to_include_in_the_project_set__2=&Select the projects to include in the Team Project Set: ExportProjectSetMainPage.Project_Set_File_Name__3=Select the export destination: @@ -177,140 +164,6 @@ ExportProjectSetMainPage.&File_name__1=&File name: TeamPreferencePage.General_settings_for_Team_support_1=General settings for Team support TeamPreferencePage.&Use_Incoming/Outgoing_mode_when_synchronizing_2=&Use Incoming/Outgoing mode when synchronizing -TargetSiteExportWizard.Target_Site=Target Site -TargetSiteExportWizard.Export_a_Target_Site=Export a target site -TargetSiteExportWizard.Creation_Question=Should I? -TargetSiteExportWizard.Create_dir=Would you like to create the directory, since it does not currently exist? -TargetSiteExportWizard.Export_Problems=Bad things happened! -TargetSiteExportWizard.Directory_creation_error=I was unable to create a new directory. Make sure you have write permissions in the appropriate area of the filesystem. -TargetSiteExportWizard.Overwrite_Question=Do you really want to? -TargetSiteExportWizard.Overwrite_file=Would you like to overwrite the file you have selected? - -ExportTargetSiteMainPage.Select_Sites=Select the sites to export -ExportTargetSiteMainPage.folder_specified=You cannot export to a directory! -ExportTargetSiteMainPage.Target_Site_Filename=Target site Filename -ExportTargetSiteMainPage.File_name=File name -ExportTargetSiteMainPage.Browse=Browse -ExportTargetSiteMainPage.Target_Site_Files=Target site files -ExportTargetSiteMainPage.default=targetSite.tsf - -ImportTargetSiteMainPage.nonexistent_file=No such file exists on your filesystem! -ImportTargetSiteMainPage.folder_specified=That is a directory, not a file! -ImportTargetSiteMainPage.File_name=File name -ImportTargetSiteMainPage.Browse=Browse -ImportTargetSiteMainPage.Target_Site_Files=Target site files - -NatureToPropertyAction.label=Convert Nature -NatureToPropertyAction.message=Could not remove the nature from one or more of the selected projects. -NatureToPropertyAction.multiMessage=Could not write .project file - -TargetSiteImportWizard.Target_Site=Target Site -TargetSiteImportWizard.Import_Target_Site=Import a Target site - -############################################### -# Target Management Messages -############################################### - -TargetSiteCreationWizard.windowTitleProject=Target a Site -TargetSiteCreationWizard.windowTitleNoProject=New Site -TargetSiteCreationWizard.label=Create a site connection -TargetSiteCreationWizard.description=Select the type of site you want to target. - -TargetSiteCreationWizard.mappingPageTitle=Specify the location on the site -TargetSiteCreationWizard.siteSelectionPage=Select or create a site - -SiteSelectionPage.description=Select an existing site or create a new site where you want to upload your resources to. -SiteSelectionPage.label=Select an existing site or create a new one: -SiteSelectionPage.useExisting=&Use Existing Site -SiteSelectionPage.createNew=&Create a new Site -SiteSelectionPage.disconnectTarget=&Disconnect from Site - -GetAsProject.thisResourceExists=The resource ''{0}'' already exists in the workspace. Overwrite? -GetAsProject.thisExternalFileExists=The folder ''{0}'' exists in the local file system. Overwrite? -GetAsProject.confirmOverwrite=Confirm Overwrite -GetAsProject.taskName1=Downloading ''{0}'' -GetAsProject.taskNameN=Downloading {0} folders -GetAsProject.errorCreatingProject=Error creating project: {0} -GetAsProject.errorGettingResources=Error getting resources - -GetAs.checkoutFailed=Problems encountered receiving the remote folder -GetAs.enterProjectTitle=Downloading ''{0}'' As... -GetAs.taskname=Downloading ''{0}'' as ''{1}'' - -Error=Error - -CreateNewFolderAction.errorCreatingFolder=Error creating the remote folder. -CreateNewFolderAction.title=New Remote Folder -CreateNewFolderAction.message=Enter the name for the new remote folder: -CreateNewFolderAction.newFolderName=New Folder - -GetAction.title=Download -GetAction.working=Downloading from ''{0}''... - -PutAction.title=Upload -PutAction.working=Uploading to ''{0}''... - -SiteExplorerView.addSiteAction=Target &Site -SiteExplorerView.addSiteActionTooltip=Add a Site -SiteExplorerView.newFolderAction=Fo&lder... -SiteExplorerView.newMenu=&New -SiteExplorerView.Name_1=Name -SiteExplorerView.Size_2=Size -SiteExplorerView.Modified_3=Modified -SiteExplorerView.URL_4=URL -SiteExplorerView.mappedProjects={0} is mapped to {1} -SiteExplorerView.projectsAlreadyMapped=The selected sites are being used by projects in your workspace. You must disconnect the projects from the Sites before discarding them. -SiteExplorerView.unmapProjectsAndDisconnect=Disconnect projects from these sites then discard the sites -SiteExplorerView.unmapDialogTitle=Warning - -CreateNewFolderAction.creatingFolder=Creating Folder -CreateNewFolderAction.suggestedNameProgress=Retrieving existing folder names... -CreateNewFolderAction.suggestedNameConcat={0}_{1} - -SiteExplorerView.promptForDeletingSites=Are you sure you want to discard {0} site(s)? -SiteExplorerView.promptForDeletingSitesTitle=Confirm Discarding Sites - -SiteExplorerViewLabelProvider.fileSize={0} KB - -MappingSelectionPage.description=Specify the location on the site where you want to target your resources. -MappingSelectionPage.label=Select the site or a folder: -MappingSelectionPage.newFolderLabel=&Create Folder... -MappingSelectionPage.mappingTitle=Select the location on the site - -ConfigureTargetWizardQuestion_2=Question -ConfigureTargetWizardError_6=Error -ConfigureTargetWizardError_mapping_the_project_with_this_site_7=Error mapping the project with this site -ConfigureTargetWizardURL_doesn__t_exist_on_the_server_8=URL doesn\'t exist on the server -ConfigureTargetWizardValidating_connection_to_Site..._9=Validating connection to Site... -ConfigureTargetWizardConnection_Error_10=Connection Error -ConfigureTargetWizard.alreadyMapped=''{0}'' is already targeted to ''{1}''. Are you sure you want to change this? -ConfigureTargetWizard.errorOccurred=An error occurred connecting to ''{0}''.\n\nCode: {1}\nMessage: {2}\n\nDo you still want to keep this target? -ConfigureTargetWizard.errorUnmappingProject=An error occurred trying to disconnect this project. - -GetAction.Exception_getting_provider_2=Exception getting provider -GetAction.confirmFileOverwrite=You have local changes which you are about to overwrite. Do you wish to continue? -GetAction.confirmFileOverwriteTitle=Confirm Overwrite - -TargetSyncAction.errorEncountered=An error occurred performing the action - -GetSyncAction.Getting..._1=Downloading... -PutAction.Exception_getting_provider_2=Exception getting provider -PutSyncAction.Putting..._1=Uploading... - -TargetCatchupReleaseViewer.Get_1=&Download -TargetCatchupReleaseViewer.Put_2=&Upload - -SiteSelectionPage.siteLabelCurrentWithMapping={0} (currently as {1}) -SiteSelectionPage.siteLabelCurrent={0} (current) - -UploadAction.Exception_getting_provider=Exception getting provider -UploadAction.working=Uploading to ''{0}''... -UploadAction.noDirtyTitle=No Dirty Resources Found -UploadAction.noDirtyMessage=There were no dirty resources found to upload. -UploadAction.confirmDeletionTitle=Confirm Deletion -UploadAction.confirmFileDeletionMessage=File ''{0}'' has been deleted locally. Do you want to delete it remotely? -UploadAction.problemMessage=Problems occurred uploading. - SynchronizeView.noSubscribersMessage=Synchronize resources with their remote to display them here. Some Team plugins may also show resources here automatically when their plugin is activated. SyncViewerDirectionFilters.incomingTitle=Incoming @@ -344,12 +197,15 @@ action.collapseAll.tooltip=Collapse All action.collapseAll.description=Collapse All action.collapseAll.image=collapseall.gif +action.configureSchedulel.label=Schedule... +action.configureSchedulel.tooltip=Configure the Refresh Schedule... + action.changeFilters.label=Filters... action.changeFilters.tooltip=Select change filters action.changeFilters.description=Select which change filters to apply in Synchronize view action.changeFilters.image=filter_change.gif -action.refreshWithRemote.label=Refresh with remote +action.refreshWithRemote.label=&Refresh with remote action.refreshWithRemote.tooltip=Refresh with remote action.refreshWithRemote.description=Refresh with remote action.refreshWithRemote.image=refresh.gif @@ -399,7 +255,8 @@ action.removePage.tooltip=Remove action.removePage.description=Remove action.removePage.image=rem_co.gif -action.expandAll.label=Expand All +action.expandAll.label=E&xpand All +action.open.label=&Open action.openInCompareEditor.label=Open In Compare Editor action.cancelSubscriber.label=Cancel @@ -430,16 +287,14 @@ StatisticsPanel.noWorkingSet=<No Working Set> StatisticsPanel.workingSetTooltip=Double-click to change the working set applied to the Synchronize View. StatisticsPanel.numbersTooltip=The number of ''{0}'' changes in the entire workspace. StatisticsPanel.numbersWorkingSetTooltip=The number of ''{0}'' changes in working set ''{1}'' versus those in the entire workspace. +StatisticsPanel.numberTotal={0} changes -SyncViewerPreferencePage.6=Synchronize view preferences -SyncViewerPreferencePage.7=Team Synchronize View settings: +SyncViewerPreferencePage.6=General Synchronize Settings +SyncViewerPreferencePage.7=General Team Settings: SyncViewerPreferencePage.8=Display SyncViewerPreferencePage.9=Compress in-sync folder paths when using the tree view SyncViewerPreferencePage.10=Use incoming/outgoing mode when synchronizing SyncViewerPreferencePage.11=Refreshing with Remote -SyncViewerPreferencePage.12=Refresh with the remote resources in the background -SyncViewerPreferencePage.13=Enable a background task to refresh with remote resources -SyncViewerPreferencePage.14=How often should the background refresh run? (in minutes) SyncViewerPreferencePage.15=Perspective Switching RefreshSubscriberInputJob.1=Synchronizing ''{0}'' with remote: {1} resources @@ -453,13 +308,12 @@ CopyAction.errorMessage=There was a problem when accessing the system clipboard. PasteAction.title=&Paste PasteAction.toolTip=Paste RefactorActionGroup.0=Edi&t -SubscriberEventHandler.2=Calculating state for {0}. SynchronizeManager.7=Error notifying of added/removal of synchronize participants SynchronizeManager.8=Error initializing participants SynchronizeManager.9=Synchronize participant with id {0} is not in the registry SynchronizeManager.10=Error saving synchronize participants -SynchronizeView.1=Synchronize View -SynchronizeView.2=Synchronize View - +SynchronizeView.1=Synchronize +SynchronizeView.2=Synchronize - SyncViewerPreferencePage.19=Show all synchronization information in a resource\'s text label TeamSubscriberParticipantPage.7=Resource TeamSubscriberParticipantPage.8=In Folder @@ -469,3 +323,52 @@ AbstractSynchronizeParticipant.4=Cannot initialize participant. Wrong descriptor SynchronizeManager.11=Error creating participant instance AbstractSynchronizeParticipant.5=Exception notifying participant listeners of changes. SynchronizeManager.13=Error initializing synchronize participant +SyncViewerPreferencePage.16=Prompt at the end of a refresh even when no changes are found. +SyncViewerPreferencePage.17=Prompt at the end of a refresh if changes are found. +SyncViewerPreferencePage.30=Prompting +SyncViewerPreferencePage.31=Prompt at the end of a scheduled refresh even when no changes are found +SyncViewerPreferencePage.32=Prompt at the end of a scheduled refresh when changes are found + +ChangesSection.filterHides=The current ''{0}'' mode is empty. +ChangesSection.filterHidesSingular=However there is {0} change in the ''{1}'' mode. +ChangesSection.filterHidesPlural=However there are {0} changes in the ''{1}'' mode. +ChangesSection.filterChange=Change to ''{0}'' mode. +ChangesSection.workingSetHiding=The current working set ''{0}'' is hiding changes in your workspace. +ChangesSection.workingSetRemove=Remove working set. +ChangesSection.noChanges=No changes in ''{0}''. +Utils.22=Incoming +Utils.23=Outgoing +Utils.24=Incoming/Outgoing +Utils.25=Conflicting +Utils.26=unknown mode +RefreshCompleteDialog.4=Team Resfresh Complete - {0} +RefreshCompleteDialog.5={0} new changes found +RefreshCompleteDialog.6=No new changes found +RefreshCompleteDialog.7=refreshing the following {0} resource(s): +RefreshCompleteDialog.13=SyncViewerPreferencePage.16 +RefreshCompleteDialog.14=SyncViewerPreferencePage.17 +RefreshCompleteDialog.15=SyncViewerPreferencePage.31 +RefreshCompleteDialog.16=SyncViewerPreferencePage.32 +RefreshCompleteDialog.17=Preview Changes >> +RefreshCompleteDialog.18=<< Preview Changes +RefreshUserNotificationPolicy.0=Refresh of ''{0}'' Complete. +ConfigureRefreshScheduleDialog.0=Configure Refresh Schedule - {0} +ConfigureRefreshScheduleDialog.1=You can allow ''{0}'' to periodically refresh it's synchronization state in the background. +ConfigureRefreshScheduleDialog.1a=The last refresh occured at: {0} +ConfigureRefreshScheduleDialog.2=Don't schedule the refresh operation to run periodically. +ConfigureRefreshScheduleDialog.3=Using the following schedule: +ConfigureRefreshScheduleDialog.4=Every: +ConfigureRefreshScheduleDialog.5=hour(s) +ConfigureRefreshScheduleDialog.6=minutes(s) +ConfigureRefreshScheduleDialog.7=Number must be a positive number greater than 0 +ConfigureRefreshScheduleDialog.8=Number must be a positive number greater than 0 +RefreshSchedule.6=\ ({0} changes found) +RefreshSchedule.7=\ (No changes found) +RefreshSchedule.8=Not Scheduled +RefreshSchedule.9=hours +RefreshSchedule.10=minutes +RefreshSchedule.11=hour +RefreshSchedule.12=minute +RefreshSchedule.13=Every {0} {1} +RefreshSchedule.14=Scheduled refresh of ''{0}'' +DiffNodeControllerHierarchical.0=Updating labels diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/preferences/SyncViewerPreferencePage.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/preferences/SyncViewerPreferencePage.java index 379bf23ce..a423da7c9 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/preferences/SyncViewerPreferencePage.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/preferences/SyncViewerPreferencePage.java @@ -12,44 +12,29 @@ package org.eclipse.team.internal.ui.preferences; import java.text.Collator; import java.text.DateFormat; -import java.util.Arrays; -import java.util.Comparator; -import java.util.Date; +import java.util.*; import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.preference.BooleanFieldEditor; -import org.eclipse.jface.preference.FieldEditorPreferencePage; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.preference.IntegerFieldEditor; +import org.eclipse.jface.preference.*; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.eclipse.team.internal.ui.IPreferenceIds; -import org.eclipse.team.internal.ui.Policy; -import org.eclipse.team.internal.ui.TeamUIPlugin; -import org.eclipse.ui.IPerspectiveDescriptor; -import org.eclipse.ui.IPerspectiveRegistry; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPreferencePage; -import org.eclipse.ui.PlatformUI; +import org.eclipse.swt.widgets.*; +import org.eclipse.team.internal.ui.*; +import org.eclipse.ui.*; /** * This area provides the widgets for providing the CVS commit comment */ public class SyncViewerPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage, IPreferenceIds { - private BooleanFieldEditor bkgRefresh = null; - private BooleanFieldEditor bkgScheduledRefresh = null; - private IntegerFieldEditor2 scheduledDelay = null; private BooleanFieldEditor compressFolders = null; private BooleanFieldEditor showSyncInLabels = null; - - private Group refreshGroup; + private BooleanFieldEditor promptWithChanges = null; + private BooleanFieldEditor promptWhenNoChanges = null; + private BooleanFieldEditor promptWithChangesBkg = null; + private BooleanFieldEditor promptWhenNoChangesBkg = null; private static class PerspectiveDescriptorComparator implements Comparator { /* @@ -65,73 +50,6 @@ public class SyncViewerPreferencePage extends FieldEditorPreferencePage implemen } } - class IntegerFieldEditor2 extends IntegerFieldEditor { - /* (non-Javadoc) - * @see org.eclipse.jface.preference.FieldEditor#createControl(org.eclipse.swt.widgets.Composite) - */ - protected void createControl(Composite parent) { - super.createControl(parent); - } - - public IntegerFieldEditor2(String name, String labelText, Composite parent, int size) { - super(name, labelText, parent, size); - } - - protected boolean checkState() { - Text control= getTextControl(); - if (!control.isEnabled()) { - clearErrorMessage(); - return true; - } - return super.checkState(); - } - - /** - * Overrode here to be package visible. - */ - protected void refreshValidState() { - super.refreshValidState(); - } - - /** - * Only store if the text control is enabled - * @see FieldEditor#doStore() - */ - protected void doStore() { - Text text = getTextControl(); - if (text.isEnabled()) { - super.doStore(); - } - } - /** - * Clears the error message from the message line if the error - * message is the error message from this field editor. - */ - protected void clearErrorMessage() { - if (getPreferencePage() != null) { - String message= getPreferencePage().getErrorMessage(); - if (message != null) { - if(getErrorMessage().equals(message)) { - super.clearErrorMessage(); - } - - } else { - super.clearErrorMessage(); - } - } - } - } - - class BooleanFieldEditor2 extends BooleanFieldEditor { - public BooleanFieldEditor2(String name, String labelText, int style, Composite parent) { - super(name, labelText, style, parent); - } - - protected void refreshValidState() { - updateEnablements(); - } - } - public SyncViewerPreferencePage() { super(GRID); setTitle(Policy.bind("SyncViewerPreferencePage.6")); //$NON-NLS-1$ @@ -151,8 +69,6 @@ public class SyncViewerPreferencePage extends FieldEditorPreferencePage implemen * @see org.eclipse.jface.preference.FieldEditorPreferencePage#createFieldEditors() */ public void createFieldEditors() { - - GridData data; Group displayGroup = createGroup(getFieldEditorParent(), Policy.bind("SyncViewerPreferencePage.8")); //$NON-NLS-1$ compressFolders = new BooleanFieldEditor(SYNCVIEW_COMPRESS_FOLDERS, Policy.bind("SyncViewerPreferencePage.9"), SWT.NONE, displayGroup); //$NON-NLS-1$ @@ -160,19 +76,18 @@ public class SyncViewerPreferencePage extends FieldEditorPreferencePage implemen showSyncInLabels = new BooleanFieldEditor(SYNCVIEW_VIEW_SYNCINFO_IN_LABEL, Policy.bind("SyncViewerPreferencePage.19"), SWT.NONE, displayGroup); //$NON-NLS-1$ addField(showSyncInLabels); - refreshGroup = createGroup(getFieldEditorParent(), Policy.bind("SyncViewerPreferencePage.11")); //$NON-NLS-1$ + Group promptGroup = createGroup(getFieldEditorParent(), Policy.bind("SyncViewerPreferencePage.30")); //$NON-NLS-1$ - bkgRefresh = new BooleanFieldEditor(SYNCVIEW_BACKGROUND_SYNC, Policy.bind("SyncViewerPreferencePage.12"), SWT.NONE, refreshGroup); //$NON-NLS-1$ - addField(bkgRefresh); + promptWhenNoChanges = new BooleanFieldEditor(SYNCVIEW_VIEW_PROMPT_WHEN_NO_CHANGES, Policy.bind("SyncViewerPreferencePage.16"), SWT.NONE, promptGroup); //$NON-NLS-1$ + addField(promptWhenNoChanges); + promptWithChanges = new BooleanFieldEditor(SYNCVIEW_VIEW_PROMPT_WITH_CHANGES, Policy.bind("SyncViewerPreferencePage.17"), SWT.NONE, promptGroup); //$NON-NLS-1$ + addField(promptWithChanges); - bkgScheduledRefresh = new BooleanFieldEditor2(SYNCVIEW_SCHEDULED_SYNC, Policy.bind("SyncViewerPreferencePage.13"), SWT.NONE, refreshGroup); //$NON-NLS-1$ - addField(bkgScheduledRefresh); - - scheduledDelay = new IntegerFieldEditor2(SYNCVIEW_DELAY, Policy.bind("SyncViewerPreferencePage.14"), refreshGroup, 2); //$NON-NLS-1$ - addField(scheduledDelay); + promptWhenNoChangesBkg = new BooleanFieldEditor(SYNCVIEW_VIEW_BKG_PROMPT_WHEN_NO_CHANGES, Policy.bind("SyncViewerPreferencePage.31"), SWT.NONE, promptGroup); //$NON-NLS-1$ + addField(promptWhenNoChangesBkg); + promptWithChangesBkg = new BooleanFieldEditor(SYNCVIEW_VIEW_BKG_PROMPT_WITH_CHANGES, Policy.bind("SyncViewerPreferencePage.32"), SWT.NONE, promptGroup); //$NON-NLS-1$ + addField(promptWithChangesBkg); - updateLastRunTime(createLabel(refreshGroup, null, 0)); - Group perspectiveGroup = createGroup(getFieldEditorParent(), Policy.bind("SyncViewerPreferencePage.15")); //$NON-NLS-1$ createLabel(perspectiveGroup, Policy.bind("SynchronizationViewPreference.defaultPerspectiveDescription"), 1); //$NON-NLS-1$ @@ -187,9 +102,7 @@ public class SyncViewerPreferencePage extends FieldEditorPreferencePage implemen addField(comboEditor); Dialog.applyDialogFont(getFieldEditorParent()); - updateLayout(displayGroup); updateLayout(perspectiveGroup); - updateLayout(refreshGroup); getFieldEditorParent().layout(true); } @@ -233,12 +146,12 @@ public class SyncViewerPreferencePage extends FieldEditorPreferencePage implemen private void updateLastRunTime(Label label) { String text; - long mills = TeamUIPlugin.getPlugin().getRefreshJob().getLastTimeRun(); + long mills = 0; if(mills == 0) { String never = Policy.bind("SyncViewPreferencePage.lastRefreshRunNever"); //$NON-NLS-1$ text = Policy.bind("SyncViewPreferencePage.lastRefreshRun", never); //$NON-NLS-1$ } else { - Date lastTimeRun = new Date(TeamUIPlugin.getPlugin().getRefreshJob().getLastTimeRun()); + Date lastTimeRun = new Date(mills); String sLastTimeRun = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(lastTimeRun); text = Policy.bind("SyncViewPreferencePage.lastRefreshRun", sLastTimeRun); //$NON-NLS-1$ } @@ -255,9 +168,9 @@ public class SyncViewerPreferencePage extends FieldEditorPreferencePage implemen * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) */ public void propertyChange(PropertyChangeEvent event) { - if(event.getSource() == bkgScheduledRefresh || event.getSource() == scheduledDelay) { - updateEnablements(); - } + //if(event.getSource() == bkgScheduledRefresh || event.getSource() == scheduledDelay) { + // updateEnablements(); + // } super.propertyChange(event); } @@ -278,9 +191,9 @@ public class SyncViewerPreferencePage extends FieldEditorPreferencePage implemen } protected void updateEnablements() { - boolean enabled = bkgScheduledRefresh.getBooleanValue(); - scheduledDelay.setEnabled(enabled, refreshGroup); - scheduledDelay.refreshValidState(); + //boolean enabled = bkgScheduledRefresh.getBooleanValue(); + //scheduledDelay.setEnabled(enabled, refreshGroup); + //scheduledDelay.refreshValidState(); } /** diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/registry/SynchronizeParticipantDescriptor.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/registry/SynchronizeParticipantDescriptor.java index c52c42e59..f1675c65d 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/registry/SynchronizeParticipantDescriptor.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/registry/SynchronizeParticipantDescriptor.java @@ -102,7 +102,7 @@ public class SynchronizeParticipantDescriptor implements ISynchronizeParticipant // Sanity check. if ((label == null) || (className == null) || (identifier == null)) { - throw new CoreException(new Status(IStatus.ERROR, configElement.getDeclaringExtension().getDeclaringPluginDescriptor().getUniqueIdentifier(), 0, "Invalid extension (missing label or class name): " + id, //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, configElement.getDeclaringExtension().getDeclaringPluginDescriptor().getUniqueIdentifier(), 0, "Invalid extension (missing label or class name): " + identifier, //$NON-NLS-1$ null)); } diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/CatchupReleaseViewer.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/CatchupReleaseViewer.java deleted file mode 100644 index 8b8398851..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/CatchupReleaseViewer.java +++ /dev/null @@ -1,734 +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.ui.sync; - - -import java.lang.reflect.InvocationTargetException; -import java.util.Iterator; - -import org.eclipse.compare.BufferedContent; -import org.eclipse.compare.CompareConfiguration; -import org.eclipse.compare.IEditableContent; -import org.eclipse.compare.ITypedElement; -import org.eclipse.compare.NavigationAction; -import org.eclipse.compare.internal.CompareUIPlugin; -import org.eclipse.compare.structuremergeviewer.DiffContainer; -import org.eclipse.compare.structuremergeviewer.DiffElement; -import org.eclipse.compare.structuremergeviewer.DiffTreeViewer; -import org.eclipse.compare.structuremergeviewer.Differencer; -import org.eclipse.compare.structuremergeviewer.IDiffContainer; -import org.eclipse.compare.structuremergeviewer.IDiffElement; -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.jface.action.Action; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.IToolBarManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.jface.dialogs.ProgressMonitorDialog; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerFilter; -import org.eclipse.jface.viewers.ViewerSorter; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.KeyAdapter; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.team.core.sync.ILocalSyncElement; -import org.eclipse.team.core.sync.IRemoteSyncElement; -import org.eclipse.team.internal.ui.IHelpContextIds; -import org.eclipse.team.internal.ui.Policy; -import org.eclipse.team.internal.ui.TeamUIPlugin; -import org.eclipse.team.ui.ISharedImages; -import org.eclipse.ui.IActionBars; -import org.eclipse.ui.IPageLayout; -import org.eclipse.ui.IViewPart; -import org.eclipse.ui.IViewSite; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.help.WorkbenchHelp; -import org.eclipse.ui.views.navigator.ResourceNavigator; - -/** - * <b>Note:</b> This class/interface is part of an interim API that is still under - * development and expected to change significantly before reaching stability. - * It is being made available at this early stage to solicit feedback from pioneering - * adopters on the understanding that any code that uses this API will almost - * certainly be broken (repeatedly) as the API evolves. - * - * This viewer adds a custom filter and some merge actions. - * Note this is a layer breaker and needs to be refactored. Viewers should - * not contain references to workbench actions. Actions should be contributed - * by the view. - */ -public abstract class CatchupReleaseViewer extends DiffTreeViewer { - - class ShowInNavigatorAction extends Action implements ISelectionChangedListener { - IViewSite viewSite; - public ShowInNavigatorAction(IViewSite viewSite, String title) { - super(title, null); - this.viewSite = viewSite; - } - public void run() { - showSelectionInNavigator(viewSite); - } - public void selectionChanged(SelectionChangedEvent event) { - IStructuredSelection selection = (IStructuredSelection)event.getSelection(); - if (selection.size() == 0) { - setEnabled(false); - return; - } - for (Iterator iter = selection.iterator(); iter.hasNext();) { - ITeamNode node = (ITeamNode)iter.next(); - if(!node.getResource().isAccessible()) { - setEnabled(false); - return; - } - } - setEnabled(true); - } - }; - - /** - * This filter hides all empty categories tree nodes. - */ - class CategoryFilter extends ViewerFilter { - static final int SHOW_INCOMING = 1; - static final int SHOW_OUTGOING = 2; - static final int SHOW_CONFLICTS = 4; - static final int SHOW_PSEUDO_CONFLICTS = 8; - - private int showMask = 0; - - CategoryFilter(int showMask) { - // Mask for all categories to show - this.showMask = showMask; - } - int getMask() { - return showMask; - } - void setMask(int mask) { - this.showMask = mask; - } - public boolean select(Viewer viewer, Object parentElement, Object element) { - // If this element has visible children, always show it. - // This is not great -- O(n^2) filtering - if (hasFilteredChildren(element)) { - return true; - } - if (element instanceof ITeamNode) { - // Filter out pseudo conflicts if requested - int kind = ((ITeamNode)element).getKind(); - if ((showMask & SHOW_PSEUDO_CONFLICTS) == 0 && (kind & IRemoteSyncElement.PSEUDO_CONFLICT) != 0) { - return false; - } - int change = ((ITeamNode)element).getKind() & IRemoteSyncElement.CHANGE_MASK; - int direction = ((ITeamNode)element).getChangeDirection(); - switch (direction) { - case ITeamNode.INCOMING: - return (showMask & SHOW_INCOMING) != 0; - case ITeamNode.OUTGOING: - return (showMask & SHOW_OUTGOING) != 0; - case Differencer.CONFLICTING: - return (showMask & SHOW_CONFLICTS) != 0; - default: - return change != 0; - } - } - // No children are visible, and this folder has no changes, so don't show it. - return false; - } - public boolean isFilterProperty(Object element, String property) { - return property.equals(PROP_KIND); - } - } - - class FilterAction extends Action { - /** - * Must subclass constructor to make it accessible to container class - */ - FilterAction(String title, ImageDescriptor image) { - super(title, image); - } - public void run() { - updateFilters(); - } - } - class SyncSorter extends ViewerSorter { - public int compare(Viewer viewer, Object e1, Object e2) { - boolean oneIsFile = e1 instanceof TeamFile; - boolean twoIsFile = e2 instanceof TeamFile; - if (oneIsFile != twoIsFile) { - return oneIsFile ? 1 : -1; - } - return super.compare(viewer, e1, e2); - } - } - - class RemoveFromTreeAction extends Action { - public RemoveFromTreeAction(String title, ImageDescriptor image) { - super(title, image); - } - public void run() { - ISelection s = getSelection(); - if (!(s instanceof IStructuredSelection) || s.isEmpty()) { - return; - } - // mark all selected nodes as in sync - for (Iterator it = ((IStructuredSelection)s).iterator(); it.hasNext();) { - Object element = it.next(); - setAllChildrenInSync((IDiffElement)element); - } - refresh(); - } - public void update() { - // Update action enablement - setEnabled(!getSelection().isEmpty()); - } - } - class ExpandAllAction extends Action { - public ExpandAllAction(String title, ImageDescriptor image) { - super(title, image); - } - public void run() { - expandSelection(); - } - public void update() { - setEnabled(!getSelection().isEmpty()); - } - } - class OpenAction extends Action { - public OpenAction(String title, ImageDescriptor image) { - super(title, image); - } - public void run() { - openSelection(); - } - public void update() { - ISelection selection = getSelection(); - if (selection instanceof IStructuredSelection) { - IStructuredSelection ss = (IStructuredSelection)selection; - if (ss.size() == 1) { - Object element = ss.getFirstElement(); - setEnabled(element instanceof TeamFile); - return; - } - } - setEnabled(false); - } - } - - // The current sync mode - private int syncMode = SyncView.SYNC_NONE; - - // Actions - private FilterAction showIncoming; - private FilterAction showOutgoing; - private FilterAction showOnlyConflicts; - private Action refresh; - private OpenAction open; - private ExpandAllAction expandAll; - private RemoveFromTreeAction removeFromTree; - private ShowInNavigatorAction showInNavigator; - private Action ignoreWhiteSpace; - private Action toggleGranularity; - - private NavigationAction showPrevious; - private NavigationAction showNext; - - // Property constant for diff mode kind - static final String PROP_KIND = "team.ui.PropKind"; //$NON-NLS-1$ - - private Action copyAllRightToLeft; - - private boolean compareFileContents = false; - - /** - * Creates a new catchup/release viewer. - */ - protected CatchupReleaseViewer(Composite parent, SyncCompareInput model) { - super(parent, model.getCompareConfiguration()); - setSorter(new SyncSorter()); - initializeActions(model); - } - - /** - * Contributes actions to the provided toolbar - */ - void contributeToActionBars(IActionBars actionBars) { - IToolBarManager toolBar = actionBars.getToolBarManager(); - - toolBar.add(new Separator()); - toolBar.add(showOnlyConflicts); - - toolBar.add(new Separator()); - toolBar.add(showNext); - toolBar.add(showPrevious); - - // Drop down menu - IMenuManager menu = actionBars.getMenuManager(); - if (syncMode == SyncView.SYNC_BOTH) { - menu.add(showIncoming); - menu.add(showOutgoing); - } - menu.add(toggleGranularity); - menu.add(ignoreWhiteSpace); - menu.add(refresh); - } - - /** - * Contributes actions to the popup menu. - */ - protected void fillContextMenu(IMenuManager manager) { - open.update(); - manager.add(open); - manager.add(new Separator()); - expandAll.update(); - manager.add(expandAll); - removeFromTree.update(); - manager.add(removeFromTree); - if (showInNavigator != null) { - manager.add(showInNavigator); - } - if (syncMode == SyncView.SYNC_COMPARE) { - if(copyAllRightToLeft.isEnabled()) { - manager.add(copyAllRightToLeft); - } - } - } - - protected void openSelection() { - ISelection selection = getSelection(); - if (selection instanceof IStructuredSelection) { - Iterator elements = ((IStructuredSelection)selection).iterator(); - while (elements.hasNext()) { - Object next = elements.next(); - openSelection(next); - } - } - } - - /** - * Method openSelection. - * @param next - */ - private void openSelection(Object next) { - if (next instanceof TeamFile) { - handleOpen(null); - } - } - - /** - * Expands to infinity all items in the selection. - */ - protected void expandSelection() { - ISelection selection = getSelection(); - if (selection instanceof IStructuredSelection) { - Iterator elements = ((IStructuredSelection)selection).iterator(); - while (elements.hasNext()) { - Object next = elements.next(); - expandToLevel(next, ALL_LEVELS); - } - } - } - - protected int getSyncMode() { - return syncMode; - } - - /** - * Returns true if the given element has filtered children, and false otherwise. - */ - protected boolean hasFilteredChildren(Object element) { - return getFilteredChildren(element).length > 0; - } - - /** - * Creates the actions for this viewer. - */ - private void initializeActions(final SyncCompareInput diffModel) { - // Mask actions - ImageDescriptor image = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_DLG_SYNC_INCOMING_ENABLED); - showIncoming = new FilterAction(Policy.bind("CatchupReleaseViewer.showIncomingAction"), image); //$NON-NLS-1$ - showIncoming.setToolTipText(Policy.bind("CatchupReleaseViewer.showIncomingAction")); //$NON-NLS-1$ - showIncoming.setDisabledImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_DLG_SYNC_INCOMING_DISABLED)); - showIncoming.setHoverImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_DLG_SYNC_INCOMING)); - - image = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_DLG_SYNC_OUTGOING_ENABLED); - showOutgoing = new FilterAction(Policy.bind("CatchupReleaseViewer.showOutgoingAction"), image); //$NON-NLS-1$ - showOutgoing.setToolTipText(Policy.bind("CatchupReleaseViewer.showOutgoingAction")); //$NON-NLS-1$ - showOutgoing.setDisabledImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_DLG_SYNC_OUTGOING_DISABLED)); - showOutgoing.setHoverImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_DLG_SYNC_OUTGOING)); - - //show only conflicts is not a HideAction because it doesnt flip bits, it sets an exact mask - image = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_DLG_SYNC_CONFLICTING_ENABLED); - showOnlyConflicts = new FilterAction(Policy.bind("CatchupReleaseViewer.showOnlyConflictsAction"), image); //$NON-NLS-1$ - showOnlyConflicts.setToolTipText(Policy.bind("CatchupReleaseViewer.showOnlyConflictsAction")); //$NON-NLS-1$ - showOnlyConflicts.setDisabledImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_DLG_SYNC_CONFLICTING_DISABLED)); - showOnlyConflicts.setHoverImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_DLG_SYNC_CONFLICTING)); - - //refresh action - image = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_REFRESH_ENABLED); - refresh = new Action(Policy.bind("CatchupReleaseViewer.refreshAction"), image) { //$NON-NLS-1$ - public void run() { - diffModel.refresh(); - } - }; - refresh.setToolTipText(Policy.bind("CatchupReleaseViewer.refreshAction")); //$NON-NLS-1$ - refresh.setDisabledImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_REFRESH_DISABLED)); - refresh.setHoverImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_REFRESH)); - - // Open Action - open = new OpenAction(Policy.bind("CatchupReleaseViewer.open"), null); //$NON-NLS-1$ - WorkbenchHelp.setHelp(open, IHelpContextIds.OPEN_ACTION); - - // Expand action - expandAll = new ExpandAllAction(Policy.bind("CatchupReleaseViewer.expand"), null); //$NON-NLS-1$ - WorkbenchHelp.setHelp(expandAll, IHelpContextIds.EXPANDALL_ACTION); - - // Toggle granularity - image = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_CONTENTS_ENABLED); - toggleGranularity = new Action(Policy.bind("CatchupReleaseViewer.Compare_File_Contents_1"), image) { //$NON-NLS-1$ - public void run() { - compareFileContents = isChecked(); - diffModel.setSyncGranularity(compareFileContents ? ILocalSyncElement.GRANULARITY_CONTENTS : ILocalSyncElement.GRANULARITY_TIMESTAMP); - updateFilters(); - } - }; - compareFileContents = diffModel.getSyncGranularity() != IRemoteSyncElement.GRANULARITY_TIMESTAMP; - toggleGranularity.setChecked(compareFileContents); - toggleGranularity.setDisabledImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_CONTENTS_DISABLED)); - toggleGranularity.setHoverImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_CONTENTS)); - - removeFromTree = new RemoveFromTreeAction(Policy.bind("CatchupReleaseViewer.removeFromView"), null); //$NON-NLS-1$ - WorkbenchHelp.setHelp(removeFromTree, IHelpContextIds.REMOVE_ACTION); - - copyAllRightToLeft = new Action(Policy.bind("CatchupReleaseViewer.copyAllRightToLeft"), null) { //$NON-NLS-1$ - public void run() { - ISelection s = getSelection(); - if (!(s instanceof IStructuredSelection) || s.isEmpty()) { - return; - } - // action is only enabled for 1 element. the for loop - final Object element = ((IStructuredSelection)s).getFirstElement(); - if(element instanceof DiffElement) { - try { - new ProgressMonitorDialog(getTree().getShell()).run(true /* fork */, true /* cancellable */, new IRunnableWithProgress() { - public void run(IProgressMonitor monitor) - throws InvocationTargetException, InterruptedException { - try { - monitor.beginTask(null, 1000); - monitor.setTaskName(Policy.bind("CatchupReleaseViewer.Copying_right_contents_into_workspace_2")); //$NON-NLS-1$ - ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() { - public void run(IProgressMonitor monitor) throws CoreException { - try { - monitor.beginTask(null, 100); - copyAllRightToLeft((DiffElement)element, monitor); - } finally { - monitor.done(); - } - } - }, Policy.subInfiniteMonitorFor(monitor, 1000)); - } catch(CoreException e) { - throw new InvocationTargetException(e); - } finally { - monitor.done(); - } - } - }); - } catch(InvocationTargetException e) { - ErrorDialog.openError(TeamUIPlugin.getPlugin().getWorkbench().getActiveWorkbenchWindow().getShell(), Policy.bind("CatchupReleaseViewer.errorCopyAllRightToLeft"), null, null); //$NON-NLS-1$ - } catch(InterruptedException e) { - } - } - refresh(); - } - public boolean isEnabled() { - ISelection s = getSelection(); - if (!(s instanceof IStructuredSelection) || s.isEmpty()) { - return false; - } - return ((IStructuredSelection)s).size() == 1; - } - }; - - // Show in navigator - if (diffModel.getViewSite() != null) { - showInNavigator = new ShowInNavigatorAction(diffModel.getViewSite(), Policy.bind("CatchupReleaseViewer.showInNavigator")); //$NON-NLS-1$ - WorkbenchHelp.setHelp(showInNavigator, IHelpContextIds.NAVIGATOR_SHOW_ACTION); - addSelectionChangedListener(showInNavigator); - } - - // Ignore white space - image = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_IGNORE_WHITESPACE_ENABLED); - ignoreWhiteSpace = new Action(Policy.bind("CatchupReleaseViewer.ignoreWhiteSpace"), image) { //$NON-NLS-1$ - public void run() { - diffModel.setIgnoreWhitespace(isChecked()); - } - }; - ignoreWhiteSpace.setId("team.ignoreWhiteSpace"); //$NON-NLS-1$ - boolean ignore = CompareUIPlugin.getDefault().getPreferenceStore().getBoolean(CompareConfiguration.IGNORE_WHITESPACE); - ignoreWhiteSpace.setChecked(ignore); - ignoreWhiteSpace.setDisabledImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_IGNORE_WHITESPACE_DISABLED)); - ignoreWhiteSpace.setHoverImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_IGNORE_WHITESPACE)); - - // Show next and previous change - showNext = new NavigationAction(true); - showPrevious = new NavigationAction(false); - showNext.setCompareEditorInput(diffModel); - showPrevious.setCompareEditorInput(diffModel); - - // Add a double-click listener for expanding/contracting - getTree().addListener(SWT.MouseDoubleClick, new Listener() { - public void handleEvent(Event e) { - mouseDoubleClicked(e); - } - }); - - // Add an F5 listener for refresh - getTree().addKeyListener(new KeyAdapter() { - public void keyPressed(KeyEvent e) { - if (e.keyCode == SWT.F5) { - diffModel.refresh(); - } - } - }); - - // Set an initial filter -- show all changes - showIncoming.setChecked(true); - showOutgoing.setChecked(true); - showOnlyConflicts.setChecked(false); - setFilters(CategoryFilter.SHOW_INCOMING| CategoryFilter.SHOW_CONFLICTS | CategoryFilter.SHOW_OUTGOING); - } - - /** - * Method setAllChildrenInSync. - * @param iDiffElement - */ - private void setAllChildrenInSync(IDiffElement element) { - if(element instanceof DiffContainer) { - DiffContainer container = (DiffContainer)element; - IDiffElement[] children = container.getChildren(); - for (int i = 0; i < children.length; i++) { - setAllChildrenInSync(children[i]); - } - } - ((DiffElement)element).setKind(IRemoteSyncElement.IN_SYNC); - } - - protected void copyAllRightToLeft(IDiffElement element, IProgressMonitor monitor) throws CoreException { - Policy.checkCanceled(monitor); - - if(element instanceof DiffContainer) { - DiffContainer container = (DiffContainer)element; - IDiffElement[] children = container.getChildren(); - for (int i = 0; i < children.length; i++) { - copyAllRightToLeft(children[i], monitor); - } - } else if(element instanceof TeamFile) { - TeamFile file = (TeamFile)element; - if(file.getKind() != IRemoteSyncElement.IN_SYNC) { - monitor.subTask( - Policy.bind("CatchupReleaseViewer.MakingLocalLikeRemote", //$NON-NLS-1$ - Policy.toTruncatedPath(file.getMergeResource().getResource().getFullPath(), 3))); - file.setProgressMonitor(Policy.subNullMonitorFor(monitor)); - - if(file.getRight() == null || file.getLeft() == null) { - file.copy(false /* right to left */); - } - ITypedElement te = file.getLeft(); - ITypedElement rte = file.getRight(); - if(te instanceof IEditableContent) { - IEditableContent editable = (IEditableContent)te; - if(editable.isEditable()) { - if(rte instanceof BufferedContent) { - editable.setContent(((BufferedContent)rte).getContent()); - } - } - } - file.setProgressMonitor(null); - monitor.worked(1); - } - } - } - - /* - * Method declared on ContentViewer. - */ - protected void inputChanged(Object input, Object oldInput) { - super.inputChanged(input, oldInput); - // Update the refresh action - if (refresh != null) { - Tree tree = getTree(); - if (tree != null) { - refresh.setEnabled(input != null); - } - } - } - - /** - * Shows the selected resource(s) in the resource navigator. - */ - private void showSelectionInNavigator(IViewSite viewSite) { - ISelection selection = getSelection(); - if (!(selection instanceof IStructuredSelection)) { - return; - } - // Create a selection of IResource objects - Object[] selected = ((IStructuredSelection)selection).toArray(); - IResource[] resources = new IResource[selected.length]; - for (int i = 0; i < selected.length; i++) { - resources[i] = ((ITeamNode)selected[i]).getResource(); - } - ISelection resourceSelection = new StructuredSelection(resources); - - // Show the resource selection in the navigator - try { - IViewPart part = viewSite.getPage().showView(IPageLayout.ID_RES_NAV); - if (part instanceof ResourceNavigator) { - ((ResourceNavigator)part).selectReveal(resourceSelection); - } - } catch (PartInitException e) { - TeamUIPlugin.log(e); - } - } - - /** - * The mouse has been double-clicked in the tree, perform appropriate - * behaviour. - */ - private void mouseDoubleClicked(Event e) { - // Only act on single selection - ISelection selection = getSelection(); - if (selection instanceof IStructuredSelection) { - IStructuredSelection structured = (IStructuredSelection)selection; - if (structured.size() == 1) { - Object first = structured.getFirstElement(); - if (first instanceof IDiffContainer) { - // Try to expand/contract - setExpandedState(first, !getExpandedState(first)); - } - } - } - } - - /** - * @see org.eclipse.jface.viewers.StructuredViewer#handleOpen(SelectionEvent) - */ - protected void handleOpen(SelectionEvent event) { - ISelection selection = getSelection(); - if (!selection.isEmpty() && selection instanceof IStructuredSelection) { - IStructuredSelection structured = (IStructuredSelection)selection; - Object selected = structured.getFirstElement(); - if (selected instanceof TeamFile) { - updateLabels(((TeamFile)selected).getMergeResource()); - } - } - super.handleOpen(event); - } - - /** - * Subclasses may override to provide different labels for the compare configuration. - */ - protected void updateLabels(MergeResource resource) { - resource.setLabels(getCompareConfiguration()); - } - - /** - * Set the filter mask to be the exact mask specified. - */ - private void setFilters(int maskToHide) { - ViewerFilter[] filters = getFilters(); - if (filters != null) { - for (int i = 0; i < filters.length; i++) { - if (filters[i] instanceof CategoryFilter) { - CategoryFilter filter = (CategoryFilter)filters[i]; - // Set the exact match to be applied on the filter - filter.setMask(maskToHide); - refresh(); - return; - } - } - } - // No category filter found -- add one - addFilter(new CategoryFilter(maskToHide)); - } - - /** - * The sync mode has changed. Update the filters. - */ - public void syncModeChanged(int mode) { - this.syncMode = mode; - updateFilters(); - } - - /** - * Sets the viewer filtering based on the current state - * of the filter actions. - */ - void updateFilters() { - //do nothing if viewer is disposed - Control control = getControl(); - if (control == null || control.isDisposed()) - return; - - //always show conflicts - int filters = CategoryFilter.SHOW_CONFLICTS; - - //determine what other filters to apply based on current action states - switch (syncMode) { - case SyncView.SYNC_INCOMING: - case SyncView.SYNC_MERGE: - if (!showOnlyConflicts.isChecked()) { - filters |= CategoryFilter.SHOW_INCOMING; - } - break; - case SyncView.SYNC_OUTGOING: - if (!showOnlyConflicts.isChecked()) { - filters |= CategoryFilter.SHOW_OUTGOING; - } - break; - case SyncView.SYNC_BOTH: - boolean conflictsOnly = showOnlyConflicts.isChecked(); - //if showing only conflicts, don't allow these actions to happen - showIncoming.setEnabled(!conflictsOnly); - showOutgoing.setEnabled(!conflictsOnly); - if (!conflictsOnly) { - if (showIncoming.isChecked()) { - filters |= CategoryFilter.SHOW_INCOMING; - } - if (showOutgoing.isChecked()) { - filters |= CategoryFilter.SHOW_OUTGOING; - } - } - break; - } - - //determine whether to show pseudo conflicts - if (!compareFileContents) { - filters |= CategoryFilter.SHOW_PSEUDO_CONFLICTS; - } - setFilters(filters); - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/ChangedTeamContainer.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/ChangedTeamContainer.java deleted file mode 100644 index 1fbc6dee3..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/ChangedTeamContainer.java +++ /dev/null @@ -1,80 +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.ui.sync; - - -import org.eclipse.compare.structuremergeviewer.Differencer; -import org.eclipse.compare.structuremergeviewer.IDiffContainer; -import org.eclipse.compare.structuremergeviewer.IDiffElement; - -/** - * <b>Note:</b> This class/interface is part of an interim API that is still under - * development and expected to change significantly before reaching stability. - * It is being made available at this early stage to solicit feedback from pioneering - * adopters on the understanding that any code that uses this API will almost - * certainly be broken (repeatedly) as the API evolves. - * - * A node in a sync tree that represents a changed folder - * (incoming/outgoing creation or deletion). - */ -public class ChangedTeamContainer extends UnchangedTeamContainer { - private MergeResource mergeResource; - - /** - * ChangedTeamContainer constructor - */ - public ChangedTeamContainer(IDiffContainer parent, MergeResource resource, int description) { - super(parent, resource.getResource(), description); - this.mergeResource = resource; - } - - /* - * Method declared on ITeamNode. - */ - public int getChangeDirection() { - return getKind() & Differencer.DIRECTION_MASK; - } - - public int getChangeType() { - return getKind() & Differencer.CHANGE_TYPE_MASK; - } - - public String getName() { - return mergeResource.getName(); - } - - /** - * Returns the team resource managed by this object. - */ - public MergeResource getMergeResource() { - return mergeResource; - } - - /* - * Method declared on IDiffContainer - */ - public void removeToRoot(IDiffElement child) { - // Don't want to remove empty changed containers - remove(child); - } - - /** - * For debugging purposes only. - */ - public String toString() { - return "ChangedTeamContainer(" + getResource().getName() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - public void makeInSync() { - setKind(Differencer.NO_CHANGE); - } - -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/ITeamNode.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/ITeamNode.java deleted file mode 100644 index c7890a721..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/ITeamNode.java +++ /dev/null @@ -1,50 +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.ui.sync; - - -import org.eclipse.compare.structuremergeviewer.Differencer; -import org.eclipse.compare.structuremergeviewer.IDiffElement; -import org.eclipse.core.resources.IResource; - -/** - * <b>Note:</b> This class/interface is part of an interim API that is still under - * development and expected to change significantly before reaching stability. - * It is being made available at this early stage to solicit feedback from pioneering - * adopters on the understanding that any code that uses this API will almost - * certainly be broken (repeatedly) as the API evolves. - * - * Interface for a sync node that responds to team commands. - */ -public interface ITeamNode extends IDiffElement { - // Possible values for the change direction - static final int INCOMING = Differencer.RIGHT; - static final int OUTGOING = Differencer.LEFT; - static final int CONFLICTING = Differencer.CONFLICTING; - static final int NO_CHANGE = Differencer.NO_CHANGE; - - /** - * Returns the change direction for this resource. One of: - * INCOMING, OUTGOING, CONFLICTING, NO_CHANGE. - */ - public int getChangeDirection(); - - /** - * Returns the type of change for this resource. One of: - * CHANGE, DELETION, ADDITION - */ - public int getChangeType(); - - /** - * Returns the core resource represented by this node. - */ - public IResource getResource(); -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/MergeResource.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/MergeResource.java deleted file mode 100644 index 5f71df9b0..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/MergeResource.java +++ /dev/null @@ -1,166 +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.ui.sync; - - -import java.io.InputStream; - -import org.eclipse.compare.CompareConfiguration; -import org.eclipse.compare.ITypedElement; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.IRemoteResource; -import org.eclipse.team.core.sync.IRemoteSyncElement; -import org.eclipse.team.internal.ui.Policy; - -/** - * <b>Note:</b> This class/interface is part of an interim API that is still under - * development and expected to change significantly before reaching stability. - * It is being made available at this early stage to solicit feedback from pioneering - * adopters on the understanding that any code that uses this API will almost - * certainly be broken (repeatedly) as the API evolves. - * - * Encapsulates information about a resource that requires - * contact with the Team API. - */ -public class MergeResource { - private IRemoteSyncElement syncTree; - - /** - * Creates a new merge resource based on the given sync information. - */ - public MergeResource(IRemoteSyncElement syncTree) { - this.syncTree = syncTree; - } - - /** - * Returns an InputStream for the base revision of this incoming resource. - */ - public InputStream getBaseRevision() throws CoreException { - IRemoteResource remote = syncTree.getBase(); - if (remote != null && !remote.isContainer()) { - try { - return remote.getContents(new NullProgressMonitor()); - } catch (TeamException exception) { - // The remote resource has gone. - return null; - } - } - return null; - } - - public String getExtension() { - if (syncTree.isContainer()) { - return ITypedElement.FOLDER_TYPE; - } - String name = getName(); - if (name != null) { - int index = name.lastIndexOf('.'); - if (index == -1) - return ""; //$NON-NLS-1$ - if (index == (name.length() - 1)) - return ""; //$NON-NLS-1$ - return name.substring(index + 1); - } - return ITypedElement.FOLDER_TYPE; - } - - /** - * Returns an InputStream for the latest repository version of this incoming resource. - */ - public InputStream getLatestRevision() throws CoreException { - IRemoteResource remote = syncTree.getRemote(); - try { - return remote.getContents(new NullProgressMonitor()); - } catch (TeamException e) { - throw new CoreException(e.getStatus()); - } - } - - /** - * Returns an InputStream for the local resource. - */ - public InputStream getLocalStream() throws CoreException { - IResource left = syncTree.getLocal(); - if (left == null) return null; - if (left.exists() && left.getType() == IResource.FILE) { - return ((IFile)left).getContents(true); - } - return null; - } - - public String getName() { - return syncTree.getName(); - } - - /* - * @see IMergeResource#getResource. - */ - public IResource getResource() { - return syncTree.getLocal(); - } - - public IRemoteSyncElement getSyncElement() { - return syncTree; - } - - /** - * Returns true if this merge resource has a base resource, - * and false otherwise. - */ - public boolean hasBaseRevision() { - return syncTree.getBase() != null; - } - - /** - * Returns true if this merge resource has a latest revision, - * and false otherwise. - */ - public boolean hasLatestRevision() { - return syncTree.getRemote() != null; - } - - /** - * Is this a leaf node, i.e. a file? - */ - public boolean isLeaf() { - return !syncTree.isContainer(); - } - - /** - * Updates the given compare configuration with appropriate left, right - * and ancestor labels for this resource. - */ - public void setLabels(CompareConfiguration config) { - String name = getName(); - config.setLeftLabel(Policy.bind("MergeResource.workspaceFile", name)); //$NON-NLS-1$ - - - IRemoteResource remote = syncTree.getRemote(); - if (remote != null) { - config.setRightLabel(Policy.bind("MergeResource.repositoryFile", name)); //$NON-NLS-1$ - // config.setRightLabel(TeamUIPlugin.getResourceString("MergeResource.repositoryFile", new Object[] {name, remote.getVersionName()} )); - } else { - config.setRightLabel(Policy.bind("MergeResource.noRepositoryFile")); //$NON-NLS-1$ - } - - IRemoteResource base = syncTree.getBase(); - if (base != null) { - config.setAncestorLabel(Policy.bind("MergeResource.commonFile", name)); //$NON-NLS-1$ - // config.setAncestorLabel(TeamUIPlugin.getResourceString("MergeResource.commonFile", new Object[] {name, common.getVersionName()} )); - } else { - config.setAncestorLabel(Policy.bind("MergeResource.noCommonFile")); //$NON-NLS-1$ - } - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/SyncCompareInput.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/SyncCompareInput.java deleted file mode 100644 index ccb6e6a4c..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/SyncCompareInput.java +++ /dev/null @@ -1,470 +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.ui.sync; - - -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.compare.CompareConfiguration; -import org.eclipse.compare.CompareEditorInput; -import org.eclipse.compare.internal.CompareUIPlugin; -import org.eclipse.compare.structuremergeviewer.DiffContainer; -import org.eclipse.compare.structuremergeviewer.DiffNode; -import org.eclipse.compare.structuremergeviewer.ICompareInput; -import org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener; -import org.eclipse.compare.structuremergeviewer.IDiffContainer; -import org.eclipse.compare.structuremergeviewer.IDiffElement; -import org.eclipse.core.resources.IContainer; -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.NullProgressMonitor; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.action.IStatusLineManager; -import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.dialogs.ProgressMonitorDialog; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.ILocalSyncElement; -import org.eclipse.team.core.sync.IRemoteSyncElement; -import org.eclipse.team.internal.ui.Policy; -import org.eclipse.team.internal.ui.TeamUIPlugin; -import org.eclipse.ui.IViewSite; - -/** - * <b>Note:</b> This class/interface is part of an interim API that is still under - * development and expected to change significantly before reaching stability. - * It is being made available at this early stage to solicit feedback from pioneering - * adopters on the understanding that any code that uses this API will almost - * certainly be broken (repeatedly) as the API evolves. - * - * Performs a catchup or release operation on an array of resources. - */ -public abstract class SyncCompareInput extends CompareEditorInput { - private IRemoteSyncElement[] trees; - private CatchupReleaseViewer catchupReleaseViewer; - private DiffNode diffRoot; - private Shell shell; - private IViewSite viewSite; - private int granularity; - - private ICompareInputChangeListener listener = new ICompareInputChangeListener() { - public void compareInputChanged(ICompareInput source) { - SyncCompareInput.this.compareInputChanged(source); - } - }; - - /** - * Subclasses may override but must call super. - */ - protected void compareInputChanged(ICompareInput source) { - catchupReleaseViewer.update(source, new String[] {CatchupReleaseViewer.PROP_KIND}); - updateStatusLine(); - } - - /** - * Creates a new catchup or release operation. - */ - public SyncCompareInput(int granularity) { - super(new CompareConfiguration()); - privateSetSyncGranularity(granularity); - } - - /** - * Creates a new catchup or release operation. - */ - public SyncCompareInput() { - this(ILocalSyncElement.GRANULARITY_TIMESTAMP); - } - - protected abstract IRemoteSyncElement[] createSyncElements(IProgressMonitor monitor) throws TeamException; - - /* - * @see CompareEditorInput#createContents - */ - public Control createContents(Composite parent) { - Control result = super.createContents(parent); - initialSelectionAndExpansionState(); - return result; - } - - /** - * Subclasses must create and return a new CatchupReleaseViewer, and set the viewer - * using setViewer(). - */ - public abstract Viewer createDiffViewer(Composite parent); - - /** - * Returns the root node of the diff tree. - */ - public DiffNode getDiffRoot() { - return diffRoot; - } - - /** - * Returns the first diff element that is still unresolved in the - * subtree rooted at the given root element. - * Returns null if everything is resolved. - */ - private IDiffElement getFirstChange(IDiffElement root) { - if (root instanceof ITeamNode) { - ITeamNode node = (ITeamNode)root; - if (node instanceof TeamFile) { - return node; - } - } - if (root instanceof IDiffContainer) { - IDiffElement[] children = ((IDiffContainer)root).getChildren(); - IDiffElement result = null; - for (int i = 0; i < children.length; i++) { - result = getFirstChange(children[i]); - if (result != null) { - return result; - } - } - } - return null; - } - - protected Shell getShell() { - return shell; - } - - /** - * Returns the name of this operation. - * It is dipslayed in the CompareEditor's title bar. - */ - public String getTitle() { - return Policy.bind("SyncCompareInput.synchronize"); //$NON-NLS-1$ - } - - /** - * Returns the compare viewer; - */ - public CatchupReleaseViewer getViewer() { - return catchupReleaseViewer; - } - - /** - * Returns the view site, or null if this is a merge. - */ - public IViewSite getViewSite() { - return viewSite; - } - - /** - * Returns true if the model has incoming or conflicting changes. - */ - boolean hasIncomingChanges() { - if (diffRoot == null) { - return false; - } - SyncSet set = new SyncSet(new StructuredSelection(diffRoot.getChildren())); - return set.hasIncomingChanges() || set.hasConflicts(); - } - - /** - * Set an appropriate initial selection and expansion state. - */ - private void initialSelectionAndExpansionState() { - // Select the next change - IDiffElement next = getFirstChange(diffRoot); - if (next != null) { - catchupReleaseViewer.setSelection(new StructuredSelection(next), true); - } else { - catchupReleaseViewer.collapseAll(); - catchupReleaseViewer.setSelection(new StructuredSelection()); - } - } - - /** - * Performs a compare on the given selection. - * This method is called before the CompareEditor has been opened. - * If the result of the diff is empty (or an error has occured) - * no CompareEditor is opened but an Alert is shown. - */ - public Object prepareInput(final IProgressMonitor pm) throws InterruptedException, InvocationTargetException { - if (pm.isCanceled()) { - throw new InterruptedException(); - } - - try { - pm.beginTask(Policy.bind("SyncCompareInput.taskTitle"), 100); //$NON-NLS-1$ - - // Estimate 70% of the time is creating the sync elements - this.trees = createSyncElements(Policy.subMonitorFor(pm, 70)); - setMessage(null); - if (trees.length == 0) { - return null; - } - final TeamException[] exceptions = new TeamException[1]; - - IWorkspaceRunnable runnable = new IWorkspaceRunnable() { - public void run(IProgressMonitor monitor) throws CoreException { - // collect changes and build the diff tree - diffRoot = new DiffNode(0); - try { - doServerDelta(monitor); - } catch (TeamException e) { - exceptions[0] = e; - } - } - }; - if (pm.isCanceled()) { - throw new InterruptedException(); - } - // Estimate 30% of the time is doing the server delta - ResourcesPlugin.getWorkspace().run(runnable, Policy.subMonitorFor(pm, 30)); - if (exceptions[0] != null) throw exceptions[0]; - if (pm.isCanceled()) { - throw new InterruptedException(); - } - - if (!diffRoot.hasChildren()) { - diffRoot = null; - } - - updateStatusLine(); - - return diffRoot; - } catch (CoreException e) { - throw new InvocationTargetException(e); - } - } - - void doServerDelta(IProgressMonitor pm) throws TeamException { - pm.beginTask(null, trees.length * 1000); - pm.setTaskName(Policy.bind("SyncCompareInput.taskTitle")); //$NON-NLS-1$ - for (int i = 0; i < trees.length; i++) { - IRemoteSyncElement tree = trees[i]; - IProgressMonitor monitor = Policy.subMonitorFor(pm, 1000); - monitor.beginTask(null, 1000); - IDiffElement localRoot = collectResourceChanges(null, tree, monitor); - monitor.done(); - makeParents(localRoot); - } - } - - /* - * This method expects to be past a monitor that has already had it's beginTask invoked - * and has enough ticks to allow 1 unit of work per resource in the tree and an additional - * unit for each folder. - */ - protected IDiffElement collectResourceChanges(IDiffContainer parent, IRemoteSyncElement tree, IProgressMonitor pm) throws TeamException { - int type = tree.getSyncKind(getSyncGranularity(), Policy.subMonitorFor(pm, 1)); - MergeResource mergeResource = new MergeResource(tree); - - if (tree.isContainer()) { - IDiffContainer element = new ChangedTeamContainer(parent, mergeResource, type); - ILocalSyncElement[] children = tree.members(Policy.subMonitorFor(pm, 1)); - for (int i = 0; i < children.length; i++) { - collectResourceChanges(element, (IRemoteSyncElement)children[i], pm); - } - return element; - } else { - TeamFile file = new TeamFile(parent, mergeResource, type, shell); - file.addCompareInputChangeListener(listener); - return file; - } - } - - public int getSyncGranularity() { - return granularity; - } - - public void setSyncGranularity(int granularity) { - privateSetSyncGranularity(granularity); - refresh(); - } - - private void privateSetSyncGranularity(int granularity) { - this.granularity = granularity; - if (granularity != IRemoteSyncElement.GRANULARITY_TIMESTAMP) { - if (isIgnoreWhitespace()) { - this.granularity = IRemoteSyncElement.GRANULARITY_CONTENTS_IGNORE_WHITESPACE; - } else { - this.granularity = IRemoteSyncElement.GRANULARITY_CONTENTS; - } - } - } - - public void setIgnoreWhitespace(boolean ignore) { - // Set the ignore whitespace - Boolean value = ignore ? Boolean.TRUE : Boolean.FALSE; - getCompareConfiguration().setProperty(CompareConfiguration.IGNORE_WHITESPACE, value); - // Set the granularity (which queries the ignore whitespace setting) - privateSetSyncGranularity(getSyncGranularity()); - // Refresh if the granularity is file contents - if (granularity != IRemoteSyncElement.GRANULARITY_TIMESTAMP) { - refresh(); - } - } - - public boolean isIgnoreWhitespace() { - Object o = getCompareConfiguration().getProperty(CompareConfiguration.IGNORE_WHITESPACE); - if (o instanceof Boolean) { - return ((Boolean)o).booleanValue(); - } - return CompareUIPlugin.getDefault().getPreferenceStore().getBoolean(CompareConfiguration.IGNORE_WHITESPACE); - } - - /** - * Builds a DiffFolder tree under the given root for the given resource. - */ - private DiffContainer buildPath(DiffContainer root, IContainer resource) { - DiffContainer parent = root; - if (resource.getType() == IResource.ROOT) { - return root; - } - if (resource.getType() != IResource.PROJECT) { - parent = buildPath(root, resource.getParent()); - } - - DiffContainer c = (DiffContainer)parent.findChild(resource.getName()); - if (c == null) { - c = new UnchangedTeamContainer(parent, resource); - } - return c; - } - - void makeParents(IDiffElement element) { - IContainer parent = ((ITeamNode)element).getResource().getParent(); - DiffContainer container = buildPath(diffRoot, parent); - container.add(element); - } - - /** - * Performs a refresh, with progress and cancelation. - */ - public void refresh() { - final Object[] input = new Object[1]; - IRunnableWithProgress op = new IRunnableWithProgress() { - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - input[0] = prepareInput(monitor); - } - }; - try { - run(op, Policy.bind("SyncCompareInput.refresh")); //$NON-NLS-1$ - } catch (InterruptedException e) { - return; - } - - catchupReleaseViewer.setInput(input[0]); - if (input[0] == null) { - MessageDialog.openInformation(shell, Policy.bind("nothingToSynchronize"), Policy.bind("SyncCompareInput.nothingText")); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - protected void run(IRunnableWithProgress op, String problemMessage) throws InterruptedException { - ProgressMonitorDialog dialog = new ProgressMonitorDialog(shell); - try { - dialog.run(true, true, op); - } catch (InvocationTargetException e) { - Throwable throwable = e.getTargetException(); - IStatus error = null; - if (throwable instanceof TeamException) { - error = ((TeamException)throwable).getStatus(); - } else if (throwable instanceof CoreException) { - error = ((CoreException)throwable).getStatus(); - } else { - error = new Status(IStatus.ERROR, TeamUIPlugin.ID, 1, Policy.bind("simpleInternal") , throwable); //$NON-NLS-1$ - } - ErrorDialog.openError(shell, problemMessage, null, error); - TeamUIPlugin.log(error.getSeverity(), error.getMessage(), throwable); - // Throw an interrupted exception so we drop out of the sync - throw new InterruptedException(); - } - } - - public void setViewSite(IViewSite viewSite) { - this.viewSite = viewSite; - this.shell = viewSite.getShell(); - } - - public void setViewer(CatchupReleaseViewer viewer) { - this.catchupReleaseViewer = viewer; - } - - /** - * Updates the status line. - */ - public void updateStatusLine() { - if (viewSite != null && !shell.isDisposed()) { - Runnable update = new Runnable() { - public void run() { - if (!shell.isDisposed()) { - IStatusLineManager statusLine = viewSite.getActionBars().getStatusLineManager(); - if (diffRoot == null) { - statusLine.setMessage(null); - statusLine.setErrorMessage(null); - return; - } - SyncSet set = getSyncSet(new StructuredSelection(diffRoot.getChildren())); - if (set.hasConflicts()) { - statusLine.setMessage(null); - statusLine.setErrorMessage(set.getStatusLineMessage()); - } else { - statusLine.setErrorMessage(null); - statusLine.setMessage(set.getStatusLineMessage()); - } - viewSite.getActionBars().updateActionBars(); - } - } - }; - // Post or run the update - if (shell.getDisplay() != Display.getCurrent()) { - shell.getDisplay().asyncExec(update); - } else { - update.run(); - } - } - } - - protected SyncSet getSyncSet(IStructuredSelection selection) { - return new SyncSet(selection); - } - public boolean saveIfNecessary() { - if (! isSaveNeeded()) return true; - - final boolean[] result = new boolean[] { false }; - getShell().getDisplay().syncExec(new Runnable() { - public void run() { - try { - result[0] = MessageDialog.openQuestion(getShell(), Policy.bind("SyncView.saveTitle"),//$NON-NLS-1$ - Policy.bind("SyncView.saveMessage"));//$NON-NLS-1$ - if (result[0]) { - ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() { - public void run(IProgressMonitor monitor) throws CoreException { - saveChanges(monitor); - } - }, new NullProgressMonitor()); - } - } catch (CoreException e) { - IStatus status = e.getStatus(); - ErrorDialog.openError(getShell(), status.getMessage(), Policy.bind("SyncView.errorSaving"), status);//$NON-NLS-1$ - result[0] = false; - } - } - }); - return result[0]; - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/SyncSet.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/SyncSet.java deleted file mode 100644 index 55808a083..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/SyncSet.java +++ /dev/null @@ -1,288 +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.ui.sync; - - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; - -import org.eclipse.compare.structuremergeviewer.Differencer; -import org.eclipse.compare.structuremergeviewer.IDiffContainer; -import org.eclipse.compare.structuremergeviewer.IDiffElement; -import org.eclipse.core.resources.IResource; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.team.core.sync.IRemoteSyncElement; -import org.eclipse.team.internal.ui.Policy; - -/** - * <b>Note:</b> This class/interface is part of an interim API that is still under - * development and expected to change significantly before reaching stability. - * It is being made available at this early stage to solicit feedback from pioneering - * adopters on the understanding that any code that uses this API will almost - * certainly be broken (repeatedly) as the API evolves. - * - * This class contains a set of resources that are slated to be - * synchronized. It performs various operations on the - * set in preparation for catchup/release. - */ -public class SyncSet { - private HashSet set; - - /** - * Creates a new sync set on the nodes in the given selection. - */ - public SyncSet(IStructuredSelection nodeSelection) { - this.set = new HashSet(nodeSelection.size() + 1); - collectNodes(nodeSelection); - } - - /** - * Collects all nodes to which this action will apply. This means - * all nodes in the selection, plus all their children. - */ - private void collectNodes(IStructuredSelection selection) { - Object[] nodes = selection.toArray(); - for (int i = 0; i < nodes.length; i++) { - recursivelyAdd((ITeamNode)nodes[i]); - } - } - - /** - * Adds all parent creations for the given node to the sync set. - */ - private void collectParentCreations(ITeamNode node) { - IDiffElement parent = node.getParent(); - if (parent != null && parent instanceof ITeamNode) { - if (parent.getKind() != IRemoteSyncElement.IN_SYNC) { - set.add(parent); - collectParentCreations((ITeamNode)parent); - } - } - } - - /** - * Returns all nodes in the set that have changes - */ - public ITeamNode[] getChangedNodes() { - ArrayList nodeList = new ArrayList(set.size()); - for (Iterator it = set.iterator(); it.hasNext();) { - ITeamNode node = (ITeamNode)it.next(); - int dir = node.getChangeDirection(); - // We assume changed nodes of the wrong type have been culled - // during set creation. - if (dir != Differencer.NO_CHANGE) { - nodeList.add(node); - } - } - ITeamNode[] nodes = new ITeamNode[nodeList.size()]; - nodeList.toArray(nodes); - return nodes; - } - - /** - * Returns the resources from all the nodes in this set. - */ - public IResource[] getResources() { - ITeamNode[] changed = getChangedNodes(); - IResource[] resources = new IResource[changed.length]; - for (int i = 0; i < changed.length; i++) { - resources[i] = changed[i].getResource(); - } - return resources; - } - - /** - * Returns a message for the status line describing this sync set. - */ - public String getStatusLineMessage() { - int incoming = 0; - int outgoing = 0; - int conflicts = 0; - for (Iterator it = set.iterator(); it.hasNext();) { - ITeamNode next = (ITeamNode)it.next(); - switch (next.getChangeDirection()) { - case IRemoteSyncElement.INCOMING: - incoming++; - break; - case IRemoteSyncElement.OUTGOING: - outgoing++; - break; - case IRemoteSyncElement.CONFLICTING: - conflicts++; - break; - } - } - StringBuffer result = new StringBuffer(); - - if (conflicts == 0) { - result.append(Policy.bind("SyncSet.noConflicts")); //$NON-NLS-1$ - } else { - result.append(Policy.bind("SyncSet.conflicts", new Object[] {Integer.toString(conflicts)} )); //$NON-NLS-1$ - } - if (incoming == 0) { - result.append(Policy.bind("SyncSet.noIncomings")); //$NON-NLS-1$ - } else { - result.append(Policy.bind("SyncSet.incomings", new Object[] {Integer.toString(incoming)} )); //$NON-NLS-1$ - } - if (outgoing == 0) { - result.append(Policy.bind("SyncSet.noOutgoings")); //$NON-NLS-1$ - } else { - result.append(Policy.bind("SyncSet.outgoings", new Object[] {Integer.toString(outgoing)} )); //$NON-NLS-1$ - } - return result.toString(); - } - - /** - * Returns true if there are any conflicting nodes in the set, and - * false otherwise. - */ - public boolean hasConflicts() { - for (Iterator it = set.iterator(); it.hasNext();) { - if (((ITeamNode)it.next()).getChangeDirection() == IRemoteSyncElement.CONFLICTING) { - return true; - } - } - return false; - } - - /** - * Returns true if this sync set has incoming changes. - * Note that conflicts are not considered to be incoming changes. - */ - public boolean hasIncomingChanges() { - for (Iterator it = set.iterator(); it.hasNext();) { - if (((ITeamNode)it.next()).getChangeDirection() == IRemoteSyncElement.INCOMING) { - return true; - } - } - return false; - } - - /** - * Returns true if this sync set has outgoing changes. - * Note that conflicts are not considered to be outgoing changes. - */ - public boolean hasOutgoingChanges() { - for (Iterator it = set.iterator(); it.hasNext();) { - if (((ITeamNode)it.next()).getChangeDirection() == IRemoteSyncElement.OUTGOING) { - return true; - } - } - return false; - } - - /** - * Returns true if this sync set has auto-mergeable conflicts. - */ - public boolean hasAutoMergeableConflicts() { - for (Iterator it = set.iterator(); it.hasNext();) { - ITeamNode node = (ITeamNode)it.next(); - if ((node.getKind() & IRemoteSyncElement.AUTOMERGE_CONFLICT) != 0) { - return true; - } - } - return false; - } - - /** - * Adds the given node, plus all its children, to the given set. - */ - private void recursivelyAdd(ITeamNode node) { - // Add the node and recurse - if (set.add(node)) { - if (node instanceof IDiffContainer) { - IDiffElement[] children = ((IDiffContainer)node).getChildren(); - for (int i = 0; i < children.length; i++) { - if (children[i] instanceof ITeamNode) { - recursivelyAdd((ITeamNode)children[i]); - } - } - } - // Add any created parents (can't release or load a - // resource creation without including new parents) - collectParentCreations(node); - } - } - - /** - * Removes all conflicting nodes from this set. - */ - public void removeConflictingNodes() { - for (Iterator it = set.iterator(); it.hasNext();) { - ITeamNode node = (ITeamNode)it.next(); - if (node.getChangeDirection() == IRemoteSyncElement.CONFLICTING) { - it.remove(); - } - } - } - /** - * Removes all outgoing nodes from this set. - */ - public void removeOutgoingNodes() { - for (Iterator it = set.iterator(); it.hasNext();) { - ITeamNode node = (ITeamNode)it.next(); - if (node.getChangeDirection() == IRemoteSyncElement.OUTGOING) { - it.remove(); - } - } - } - /** - * Removes all incoming nodes from this set. - */ - public void removeIncomingNodes() { - for (Iterator it = set.iterator(); it.hasNext();) { - ITeamNode node = (ITeamNode)it.next(); - if (node.getChangeDirection() == IRemoteSyncElement.INCOMING) { - it.remove(); - } - } - } - /** - * Removes all nodes from this set that are not auto-mergeable conflicts - */ - public void removeNonMergeableNodes() { - for (Iterator it = set.iterator(); it.hasNext();) { - ITeamNode node = (ITeamNode)it.next(); - if ((node.getKind() & IRemoteSyncElement.MANUAL_CONFLICT) != 0) { - it.remove(); - } else if (node.getChangeDirection() != ITeamNode.CONFLICTING) { - it.remove(); - } - } - } - - /** - * Removes all nodes that aren't applicable for the direction. - */ - public void removeNonApplicableNodes(int direction) { - for (Iterator it = set.iterator(); it.hasNext();) { - ITeamNode node = (ITeamNode)it.next(); - int nodeDirection = node.getKind() & IRemoteSyncElement.DIRECTION_MASK; - if (nodeDirection != IRemoteSyncElement.CONFLICTING) { - if (nodeDirection != direction) { - it.remove(); - } - } - } - } - - /** - * Remove the given node from the sync set - */ - public void remove(ITeamNode node) { - set.remove(node); - } - - protected HashSet getSyncSet() { - return set; - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/SyncView.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/SyncView.java deleted file mode 100644 index 19c5ac67d..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/SyncView.java +++ /dev/null @@ -1,532 +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.ui.sync; - - -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.compare.*; -import org.eclipse.compare.structuremergeviewer.DiffNode; -import org.eclipse.compare.structuremergeviewer.IDiffElement; -import org.eclipse.core.runtime.*; -import org.eclipse.jface.action.*; -import org.eclipse.jface.dialogs.*; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.*; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.ui.*; -import org.eclipse.team.ui.ISharedImages; -import org.eclipse.ui.*; -import org.eclipse.ui.actions.ActionFactory; -import org.eclipse.ui.actions.WorkspaceModifyOperation; -import org.eclipse.ui.help.WorkbenchHelp; -import org.eclipse.ui.part.*; - -/** - * <b>Note:</b> This class/interface is part of an interim API that is still under - * development and expected to change significantly before reaching stability. - * It is being made available at this early stage to solicit feedback from pioneering - * adopters on the understanding that any code that uses this API will almost - * certainly be broken (repeatedly) as the API evolves. - * - * This class provides a view for performing synchronizations - * between the local workspace and a repository. - */ -public class SyncView extends ViewPart implements ISaveablePart, IPropertyChangeListener { - public static final String VIEW_ID = "org.eclipse.team.ui.sync.SyncView"; //$NON-NLS-1$ - private SyncCompareInput input; - private Composite top; - - // The possible sync modes - public static final int SYNC_NONE = 0; - public static final int SYNC_INCOMING = 1; - public static final int SYNC_OUTGOING = 2; - public static final int SYNC_BOTH = 3; - public static final int SYNC_MERGE = 4; - public static final int SYNC_COMPARE = 5; - - // Titles cached for efficiency - private final String CATCHUP_TITLE = Policy.bind("SyncView.incomingModeTitle"); //$NON-NLS-1$ - private final String RELEASE_TITLE = Policy.bind("SyncView.outgoingModeTitle"); //$NON-NLS-1$ - private final String FREE_TITLE = Policy.bind("SyncView.freeModeTitle"); //$NON-NLS-1$ - - private int currentSyncMode = SYNC_NONE; - - private String viewTitle = ""; //$NON-NLS-1$ - - /** - * Action for toggling the sync mode. - */ - class SyncModeAction extends Action { - // The sync mode that this action enables - private int syncMode; - public SyncModeAction(String title, ImageDescriptor image, int mode) { - super(title, image); - this.syncMode = mode; - } - public void run() { - SyncView.this.setSyncMode(syncMode); - } - } - - private SyncModeAction incomingMode; - private SyncModeAction outgoingMode; - private SyncModeAction freeMode; - private NavigationAction next; - private NavigationAction previous; - - private class PartListener implements IPartListener { - public void partActivated(IWorkbenchPart part) { - } - public void partBroughtToTop(IWorkbenchPart part) { - } - public void partClosed(IWorkbenchPart part) { - } - public void partDeactivated(IWorkbenchPart part) { - if (part == SyncView.this && input != null) { - input.saveIfNecessary(); - } - } - public void partOpened(IWorkbenchPart part) { - } - } - - private IPartListener partListener; - - /** - * Creates a new view. - */ - public SyncView() { - super(); - } - - /* - * @see IWorkbenchPart#createPartControl - */ - public void createPartControl(Composite parent) { - top = new Composite(parent, SWT.NONE); - - //XXX Set the control data to be this part, so the compare - //frames that will eventually live in this widget hierarchy - //have some way to access the action bars for hooking global - //actions. See corresponding XXX comment in CompareEditor#findActionBars - top.setData(this); - - GridLayout layout = new GridLayout(); - layout.marginHeight = 0; - layout.marginWidth = 0; - top.setLayout(layout); - top.setLayoutData(new GridData(GridData.FILL_BOTH)); - - showDefaultContents(); - - initializeSyncModes(); - // add part listener - partListener = new PartListener(); - getViewSite().getWorkbenchWindow().getPartService().addPartListener(partListener); - WorkbenchHelp.setHelp(top, IHelpContextIds.SYNC_VIEW); - } - - public void dispose() { - // remove part listener - if (partListener != null) { - getViewSite().getWorkbenchWindow().getPartService().removePartListener(partListener); - partListener = null; - } - - if (input instanceof IPropertyChangeNotifier) - ((IPropertyChangeNotifier)input).removePropertyChangeListener(this); - super.dispose(); - } - - /** - * Makes the sync view visible in the active page. If there isn't a sync - * view registered <code>null</code> is returned. Otherwise the opened view - * part is returned. - */ - public static SyncView findViewInActivePage(IWorkbenchPage activePage) { - try { - if (activePage == null) { - activePage = TeamUIPlugin.getActivePage(); - if (activePage == null) return null; - } - IViewPart part = activePage.findView(VIEW_ID); - if (part == null) - part = activePage.showView(VIEW_ID); - return (SyncView)part; - } catch (PartInitException pe) { - return null; - } - } - - /** - * Sets up the sync modes and the actions for switching between them. - */ - private void initializeSyncModes() { - // Create the actions - incomingMode = new SyncModeAction( - Policy.bind("SyncView.incomingModeAction"), //$NON-NLS-1$ - TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_SYNC_MODE_CATCHUP_ENABLED), - SYNC_INCOMING); - incomingMode.setToolTipText(Policy.bind("SyncView.incomingModeToolTip")); //$NON-NLS-1$ - incomingMode.setChecked(false); - incomingMode.setDisabledImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_SYNC_MODE_CATCHUP_DISABLED)); - incomingMode.setHoverImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_SYNC_MODE_CATCHUP)); - - outgoingMode = new SyncModeAction( - Policy.bind("SyncView.outgoingModeAction"), //$NON-NLS-1$ - TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_SYNC_MODE_RELEASE_ENABLED), - SYNC_OUTGOING); - outgoingMode.setToolTipText(Policy.bind("SyncView.outgoingModeToolTip")); //$NON-NLS-1$ - outgoingMode.setChecked(false); - outgoingMode.setDisabledImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_SYNC_MODE_RELEASE_DISABLED)); - outgoingMode.setHoverImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_SYNC_MODE_RELEASE)); - - freeMode = new SyncModeAction( - Policy.bind("SyncView.freeModeAction"), //$NON-NLS-1$ - TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_SYNC_MODE_FREE_ENABLED), - SYNC_BOTH); - freeMode.setToolTipText(Policy.bind("SyncView.freeModeToolTip")); //$NON-NLS-1$ - freeMode.setChecked(false); - freeMode.setDisabledImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_SYNC_MODE_FREE_DISABLED)); - freeMode.setHoverImageDescriptor(TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_SYNC_MODE_FREE)); - - // Set up global actions for next and previous - next = new NavigationAction(true); - previous = new NavigationAction(false); - IActionBars actionBars = getViewSite().getActionBars(); - if (actionBars != null) { - actionBars.setGlobalActionHandler(ActionFactory.NEXT.getId(), next); - actionBars.setGlobalActionHandler(ActionFactory.PREVIOUS.getId(), previous); - actionBars.updateActionBars(); - } - } - - private boolean isEmpty(DiffNode node) { - if (node == null) return true; - if (node.getKind() != 0) return false; - IDiffElement[] children = node.getChildren(); - for (int i = 0; i < children.length; i++) { - if (!isEmpty(children[i])) return false; - } - return true; - } - private boolean isEmpty(IDiffElement element) { - if (element.getKind() != 0) return false; - if (element instanceof DiffNode) { - IDiffElement[] children = ((DiffNode)element).getChildren(); - for (int i = 0; i < children.length; i++) { - if (!isEmpty(children[i])) return false; - } - } - return true; - } - - /** - * Runs an operation and handles progress and exceptions. Returns true - * if the operation was successful, and false if there were errors or - * the user canceled. - */ - private boolean run(IRunnableWithProgress op) { - ProgressMonitorDialog dialog = new ProgressMonitorDialog(getSite().getShell()); - try { - dialog.run(true, true, op); - return true; - } catch (InvocationTargetException e) { - Throwable throwable = e.getTargetException(); - IStatus error = null; - if (throwable instanceof TeamException) { - error = ((TeamException)throwable).getStatus(); - } else if (throwable instanceof CoreException) { - error = ((CoreException)throwable).getStatus(); - } else { - error = new Status(IStatus.ERROR, TeamUIPlugin.ID, 1, Policy.bind("simpleInternal"), throwable); //$NON-NLS-1$ - } - ErrorDialog.openError(getSite().getShell(), Policy.bind("SyncView.unableSynchronize"), null, error); //$NON-NLS-1$ - TeamUIPlugin.log(error.getSeverity(), error.getMessage(), throwable); - } catch (InterruptedException e) { - } - return false; - } - - /** - * Asks the part to take focus within the workbench. - */ - public void setFocus() { - if (top != null && !top.isDisposed()) { - top.setFocus(); - } - } - - /** - * Activates the given sync mode. - */ - void setSyncMode(int mode) { - // Implement radio button behaviour - switch (mode) { - case SYNC_INCOMING: - incomingMode.setChecked(true); - outgoingMode.setChecked(false); - freeMode.setChecked(false); - setTitleWithDirtyIndicator(CATCHUP_TITLE); - break; - case SYNC_OUTGOING: - outgoingMode.setChecked(true); - incomingMode.setChecked(false); - freeMode.setChecked(false); - setTitleWithDirtyIndicator(RELEASE_TITLE); - break; - case SYNC_BOTH: - freeMode.setChecked(true); - outgoingMode.setChecked(false); - incomingMode.setChecked(false); - setTitleWithDirtyIndicator(FREE_TITLE); - break; - } - // Only update actions if there is valid input - if (input != null && input.getDiffRoot() != null && mode != currentSyncMode) { - currentSyncMode = mode; - input.getViewer().syncModeChanged(mode); - updateActions(); - } - } - - /** - * Shows default contents for the view if there is nothing to synchronize. - */ - private void showDefaultContents() { - Label label = new Label(top, SWT.WRAP); - label.setLayoutData(new GridData(GridData.FILL_BOTH)); - label.setText(Policy.bind("SyncView.text")); //$NON-NLS-1$ - } - - /** - * Shows synchronization information for the given resources in the sync view. - * @deprecated - */ - public void showSync(SyncCompareInput input) { - showSync(input, null); - } - - /** - * Shows synchronization information for the given resources in the sync - * view. - * @param input the diff tree to be displayed - * @param page the page on which to open the sync view - */ - public void showSync(SyncCompareInput input, IWorkbenchPage page) { - next.setCompareEditorInput(input); - previous.setCompareEditorInput(input); - IActionBars actionBars = getViewSite().getActionBars(); - actionBars.updateActionBars(); - - input.setViewSite(getViewSite()); - this.input = input; - currentSyncMode = SYNC_NONE; - - // listen to property notifications from our input, this - // is to support global save enablement. - if (input instanceof IPropertyChangeNotifier) - ((IPropertyChangeNotifier)input).addPropertyChangeListener(this); - - // Remove old viewer - Control[] oldChildren = top.getChildren(); - if (oldChildren != null) { - for (int i = 0; i < oldChildren.length; i++) { - oldChildren[i].dispose(); - } - } - // Remove actions from toolbar - IActionBars bars = getViewSite().getActionBars(); - bars.getToolBarManager().removeAll(); - bars.getToolBarManager().update(false); - bars.getMenuManager().removeAll(); - bars.getMenuManager().update(); - bars.updateActionBars(); - - // Display the default contents while running the diff - showDefaultContents(); - top.layout(); - - // Run the diff and stop if cancel or error occurred. - if (!run(input)) return; - - // Check for problem message - if (input.getMessage() != null) { - MessageDialog.openInformation(getSite().getShell(), Policy.bind("SyncView.unableSynchronize"), input.getMessage()); //$NON-NLS-1$ - return; - } - - // Check for empty comparison - if (isEmpty(input.getDiffRoot())) { - MessageDialog.openInformation(getSite().getShell(), Policy.bind("nothingToSynchronize"), Policy.bind("SyncView.same")); //$NON-NLS-1$ //$NON-NLS-2$ - return; - } - - // Remove the default contents - oldChildren = top.getChildren(); - if (oldChildren != null) { - for (int i = 0; i < oldChildren.length; i++) { - oldChildren[i].dispose(); - } - } - - // Show the result - Control control = input.createContents(top); - control.setLayoutData(new GridData(GridData.FILL_BOTH)); - /*TreeViewer viewer = input.getViewer(); - if (viewer != null) { - Control viewerControl = viewer.getControl(); - if (viewerControl != null && !viewerControl.isDisposed()) { - WorkbenchHelp.setHelp(viewerControl, new ViewContextComputer(this, ITeamHelpContextIds.SYNC_VIEW)); - } - }*/ - - top.layout(); - - // Set the sync mode depending on user preference - //if (TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(ISharedImages.PREF_ALWAYS_IN_INCOMING_OUTGOING)) { - // freeMode.run(); - //} else { - if (input.hasIncomingChanges()) { - incomingMode.run(); - } else { - outgoingMode.run(); - } - //} - // Reveal if fast view - try { - if (page == null) page = TeamUIPlugin.getActivePage(); - if (page != null) page.showView(VIEW_ID); - } catch (PartInitException e) { - TeamUIPlugin.log(e); - } - } - - /** - * Updates the actions for this view's action bar. - */ - private void updateActions() { - IActionBars bars = getViewSite().getActionBars(); - IToolBarManager toolBar = bars.getToolBarManager(); - IMenuManager menu = bars.getMenuManager(); - toolBar.removeAll(); - menu.removeAll(); - - toolBar.add(incomingMode); - toolBar.add(outgoingMode); - toolBar.add(freeMode); - input.getViewer().contributeToActionBars(bars); - - toolBar.update(false); - menu.update(false); - bars.updateActionBars(); - } - - /** - * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) - */ - public Object getAdapter(Class key) { - if (key == IShowInSource.class) { - return new IShowInSource() { - public ShowInContext getShowInContext() { - if (input == null || input.getViewer() == null) return null; - return new ShowInContext(null, input.getViewer().getSelection()); - } - }; - } - return super.getAdapter(key); - } - - /* (non-Javadoc) - * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor) - */ - public void doSave(IProgressMonitor monitor) { - - WorkspaceModifyOperation operation= new WorkspaceModifyOperation() { - public void execute(IProgressMonitor pm) throws CoreException { - if (input instanceof CompareEditorInput) - ((CompareEditorInput)input).saveChanges(pm); - } - }; - - Shell shell= getSite().getShell(); - - try { - - operation.run(monitor); - - firePropertyChange(PROP_DIRTY); - - } catch (InterruptedException x) { - } catch (OperationCanceledException x) { - } catch (InvocationTargetException x) { - String reason= x.getTargetException().getMessage(); - ErrorDialog.openError(getSite().getShell(), Policy.bind("SyncView.cantSaveError", reason), null, null); //$NON-NLS-1$ - } - } - - /* (non-Javadoc) - * @see org.eclipse.ui.ISaveablePart#doSaveAs() - */ - public void doSaveAs() { - } - - /* (non-Javadoc) - * @see org.eclipse.ui.ISaveablePart#isDirty() - */ - public boolean isDirty() { - if (input instanceof CompareEditorInput) - return ((CompareEditorInput)input).isSaveNeeded(); - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed() - */ - public boolean isSaveAsAllowed() { - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.ui.ISaveablePart#isSaveOnCloseNeeded() - */ - public boolean isSaveOnCloseNeeded() { - return true; - } - - /* (non-Javadoc) - * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) - */ - public void propertyChange(PropertyChangeEvent event) { - if (isDirty()) { - firePropertyChange(PROP_DIRTY); - } - setTitleWithDirtyIndicator(null); - } - - private void setTitleWithDirtyIndicator(String title) { - if(title != null) { - viewTitle = title; - } - if(isDirty()) { - setTitle(Policy.bind("SyncView.dirtyIndicatorInTitle", viewTitle)); //$NON-NLS-1$ - } else { - setTitle(viewTitle); - } - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/TeamFile.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/TeamFile.java deleted file mode 100644 index 53e84d37f..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/TeamFile.java +++ /dev/null @@ -1,393 +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.ui.sync; - - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.compare.CompareUI; -import org.eclipse.compare.ITypedElement; -import org.eclipse.compare.structuremergeviewer.DiffElement; -import org.eclipse.compare.structuremergeviewer.Differencer; -import org.eclipse.compare.structuremergeviewer.ICompareInput; -import org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener; -import org.eclipse.compare.structuremergeviewer.IDiffContainer; -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.jface.dialogs.ProgressMonitorDialog; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.util.Assert; -import org.eclipse.jface.util.ListenerList; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.team.core.sync.IRemoteSyncElement; -import org.eclipse.team.internal.core.TeamPlugin; -import org.eclipse.team.internal.ui.Policy; -import org.eclipse.team.internal.ui.TeamUIPlugin; - -/** - * <b>Note:</b> This class/interface is part of an interim API that is still under - * development and expected to change significantly before reaching stability. - * It is being made available at this early stage to solicit feedback from pioneering - * adopters on the understanding that any code that uses this API will almost - * certainly be broken (repeatedly) as the API evolves. - * - * A sync node for a version-controlled file, where the left - * side is the local file, the right side is the remote file, - * and the ancestor is the common file. - */ -public class TeamFile extends DiffElement implements ICompareInput, ITeamNode, IAdaptable { - - private MergeResource mergeResource; - - private Shell shell; - private ListenerList listeners; - - private TypedBufferedContent localByteContents; - private TypedBufferedContent commonByteContents; - private TypedBufferedContent remoteByteContents; - - boolean hasBeenSaved = false; - - private IProgressMonitor monitor; - - /** - * Creates a new file node. - */ - public TeamFile(IDiffContainer parent, MergeResource res, int changeType, Shell shell) { - super(parent, changeType); - Assert.isNotNull(res); - this.mergeResource = res; - this.shell = shell; - - commonByteContents = new TypedBufferedContent(this, false) { - public InputStream createStream() throws CoreException { - return mergeResource.getBaseRevision(); - } - }; - remoteByteContents = new TypedBufferedContent(this, false) { - protected InputStream createStream() throws CoreException { - return mergeResource.getLatestRevision(); - } - }; - - if(getResource().exists()) { - localByteContents = getLocalTypedContent(); - } else { - localByteContents = null; - } - } - - public void addCompareInputChangeListener(ICompareInputChangeListener l) { - if (listeners == null) { - listeners = new ListenerList(); - } - listeners.add(l); - } - - /* - * @see ICompareInput#copy(boolean) - */ - public void copy(boolean leftToRight) { - if (leftToRight) return; - ITypedElement right = getRight(); - ITypedElement left = getLeft(); - try { - if (left == null) { - // Addition - saveChanges(new ByteArrayInputStream(new byte[0])); - localByteContents = getLocalTypedContent(); - } else { - // deletion - saveChanges(null); - localByteContents = null; - } - } catch(CoreException e) { - TeamPlugin.log(e); - } - } - - public boolean equals(Object other) { - if (other != null && other.getClass() == getClass()) { - TeamFile file = (TeamFile) other; - return mergeResource.equals(file.mergeResource); - } - return super.equals(other); - } - - /* - * @see ICompareInput#getAncestor - */ - public ITypedElement getAncestor() { - if (mergeResource.hasBaseRevision()) { - return commonByteContents; - } - return null; - } - - /* - * Method declared on ITeamNode. - */ - public int getChangeDirection() { - return getKind() & Differencer.DIRECTION_MASK; - } - - /* - * @see ITeamNode#getChangeType() - */ - public int getChangeType() { - return getKind() & Differencer.CHANGE_TYPE_MASK; - } - - /* - * @see ITypedInput#getType - */ - public Image getImage() { - return CompareUI.getImage(getType()); - } - - /* - * @see ICompareInput#getLeft - */ - public ITypedElement getLeft() { - return localByteContents; - } - - /* - * @see ITypedInput#getName - */ - public String getName() { - if(hasBeenSaved) { - return Policy.bind("TeamFile.modified", mergeResource.getName()); //$NON-NLS-1$ - } else { - return mergeResource.getName(); - } - } - - /* - * @see ICompareInput#getRight - */ - public ITypedElement getRight() { - if (mergeResource.hasLatestRevision()) { - return remoteByteContents; - } else { - return null; - } - } - - /* - * @see ITypedInput#getType - */ - public String getType() { - return mergeResource.getExtension(); - } - - /* - * @see ICompareInput#removeCompareInputChangeListener(ICompareInputChangeListener) - */ - public void removeCompareInputChangeListener(ICompareInputChangeListener listener) { - if (listeners != null) { - listeners.remove(listener); - } - } - - /* - * @see Object - */ - public int hashCode() { - return mergeResource.hashCode(); - } - - /** - * Returns the team resource managed by this object. - * Guaranteed to be non-null. - */ - public MergeResource getMergeResource() { - return mergeResource; - } - - /** - * Returns the core resource managed by this object. - * Guaranteed to be non-null. - */ - public IResource getResource() { - return mergeResource.getResource(); - } - - /** - * For debugging purposes only. - */ - public String toString() { - return "TeamFile(" + mergeResource.getName() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - protected TypedBufferedContent getLocalTypedContent() { - // don't allow editing of outgoing deletion content. To revert from the deletion the - // user should use the appropriate sync view action. - boolean outgoingDeletion = getChangeDirection() == IRemoteSyncElement.OUTGOING && getChangeType() == IRemoteSyncElement.DELETION; - final String name = getName(); - return new TypedBufferedContent(this, !outgoingDeletion) { - protected InputStream createStream() throws CoreException { - return mergeResource.getLocalStream(); - } - public void setContent(byte[] contents) { - try { - if(contents==null) { - saveChanges(new ByteArrayInputStream(new byte[0])); - } else { - saveChanges(new ByteArrayInputStream(contents)); - } - } catch(CoreException e) { - ErrorDialog.openError(TeamUIPlugin.getPlugin().getWorkbench().getActiveWorkbenchWindow().getShell(), Policy.bind("TeamFile.saveChanges", name), null, e.getStatus()); //$NON-NLS-1$ - } - Display.getDefault().syncExec(new Runnable() { - public void run() { - fireContentChanged(); - } - }); - } - public ITypedElement replace(ITypedElement child, ITypedElement other) { - return null; - } - }; - } - - /** - * The local resource has beed modified (i.e. merged). - */ - public void merged() { - // calculate the new sync state based on the type of change that was merged. This - // logic cannot be in the IRemoteSyncElement because there is no way to update the - // base before calling getSyncKind() again. - if(getChangeDirection()==INCOMING) { - switch(getChangeType()) { - case Differencer.ADDITION: - case Differencer.CHANGE: - setKind(OUTGOING | Differencer.CHANGE); - break; - case Differencer.DELETION: - setKind(CONFLICTING | Differencer.CHANGE); - } - } else { - setKind(OUTGOING | (getKind() & Differencer.CHANGE_TYPE_MASK)); - } - hasBeenSaved = false; - } - - public void setProgressMonitor(IProgressMonitor monitor) { - this.monitor = monitor; - } - - private void saveChanges(final InputStream is) throws CoreException { - run(new IRunnableWithProgress() { - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - try { - IFile file = (IFile) getResource(); - if (is != null) { - if (!file.exists()) { - createParents(getParent(), getResource().getParent()); - file.create(is, false, monitor); - } else { - file.setContents(is, false, true, monitor); - } - } else { - file.delete(false, true, monitor); - deleteParents(getParent(), getResource().getParent()); - } - hasBeenSaved = true; - - // update the UI with the sync state change. - fireThreeWayInputChange(); - } catch (CoreException e) { - throw new InvocationTargetException(e); - } - } - }); - } - - private void createParents(IDiffContainer parentNode, IContainer parentFolder) throws CoreException { - if(!parentFolder.exists() && parentFolder.getType() != IResource.PROJECT) { - createParents(parentNode.getParent(), parentFolder.getParent()); - ((IFolder)parentFolder).create(false /* force */, true, null); - if(parentNode instanceof ChangedTeamContainer) { - ((ChangedTeamContainer)parentNode).setKind(IRemoteSyncElement.IN_SYNC); - } - } - } - - private void deleteParents(IDiffContainer parentNode, IContainer parentFolder) throws CoreException { - if(parentFolder.members().length == 0 && parentFolder.getType() != IResource.PROJECT) { - IContainer parent = parentFolder.getParent(); - parentFolder.delete(false, null); - if(parentNode instanceof ChangedTeamContainer) { - ((ChangedTeamContainer)parentNode).setKind(IRemoteSyncElement.IN_SYNC); - } - deleteParents(parentNode.getParent(), parent); - } - } - - private void run(IRunnableWithProgress runnable) throws CoreException { - try { - if(monitor == null) { - new ProgressMonitorDialog(shell).run(false, false, runnable); - } else { - runnable.run(monitor); - } - } catch (InvocationTargetException e) { - if (e.getTargetException() instanceof CoreException) { - throw (CoreException)e.getTargetException(); - } else { - throw new CoreException(new Status(IStatus.ERROR, TeamUIPlugin.ID, 0, Policy.bind("simpleInternal"), e.getTargetException())); //$NON-NLS-1$ - } - } catch (InterruptedException e) { - // Ignore - } - } - - private void fireThreeWayInputChange() { - Display.getDefault().syncExec(new Runnable() { - public void run() { - if (listeners != null) { - Object[] listenerArray = listeners.getListeners(); - // Iterate backwards so that the model gets updated last - // it might want to remove the node completely, which might - // upset other listeners. - for (int i = listenerArray.length; --i >= 0;) - ((ICompareInputChangeListener) listenerArray[i]).compareInputChanged(TeamFile.this); - } - } - }); - } - - public boolean hasBeenSaved() { - return hasBeenSaved; - } - - /** - * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) - */ - public Object getAdapter(Class adapter) { - if (adapter == IResource.class) - return mergeResource.getResource(); - return null; - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/TypedBufferedContent.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/TypedBufferedContent.java deleted file mode 100644 index f891b81b0..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/TypedBufferedContent.java +++ /dev/null @@ -1,77 +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.ui.sync; - - -import org.eclipse.compare.BufferedContent; -import org.eclipse.compare.IEditableContent; -import org.eclipse.compare.ITypedElement; -import org.eclipse.swt.graphics.Image; - -/** - * <b>Note:</b> This class/interface is part of an interim API that is still under - * development and expected to change significantly before reaching stability. - * It is being made available at this early stage to solicit feedback from pioneering - * adopters on the understanding that any code that uses this API will almost - * certainly be broken (repeatedly) as the API evolves. - * - * A content buffer for resources on a server. - */ -abstract class TypedBufferedContent extends BufferedContent implements ITypedElement, IEditableContent { - private ITeamNode node; - private boolean editable; - - /** - * Creates a new content buffer for the given team node. - */ - TypedBufferedContent(ITeamNode node, boolean editable) { - this.node = node; - this.editable = editable; - } - - public Image getImage() { - return node.getImage(); - } - - public String getName() { - return node.getName(); - } - - public String getType() { - return node.getType(); - } - - /** - * Returns true if this object can be modified. - * If it returns <code>false</code> the other methods must not be called. - * - * @return <code>true</code> if this object can be modified. - */ - public boolean isEditable() { - return editable; - } - - /** - * This is not the definitive API! - * This method is called on a parent to - * - add a child, - * - remove a child, - * - copy the contents of a child - * - * What to do is encoded in the two arguments as follows: - * add: child == null other != null - * remove: child != null other == null - * copy: child != null other != null - */ - public ITypedElement replace(ITypedElement child, ITypedElement other) { - return null; - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/UnchangedTeamContainer.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/UnchangedTeamContainer.java deleted file mode 100644 index 3b6a7a8de..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/UnchangedTeamContainer.java +++ /dev/null @@ -1,78 +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.ui.sync; - - -import org.eclipse.compare.CompareUI; -import org.eclipse.compare.ITypedElement; -import org.eclipse.compare.ResourceNode; -import org.eclipse.compare.structuremergeviewer.DiffNode; -import org.eclipse.compare.structuremergeviewer.Differencer; -import org.eclipse.compare.structuremergeviewer.IDiffContainer; -import org.eclipse.core.resources.IResource; -import org.eclipse.swt.graphics.Image; - -/** - * <b>Note:</b> This class/interface is part of an interim API that is still under - * development and expected to change significantly before reaching stability. - * It is being made available at this early stage to solicit feedback from pioneering - * adopters on the understanding that any code that uses this API will almost - * certainly be broken (repeatedly) as the API evolves. - * - * A node in a diff tree that represents a folder with no changes - * to itself, it is only a placeholder for changes in its children. - */ -public class UnchangedTeamContainer extends DiffNode implements ITeamNode { - private IResource resource; - - public UnchangedTeamContainer(IDiffContainer parent, IResource resource) { - this(parent, resource, Differencer.NO_CHANGE); - } - - public UnchangedTeamContainer(IDiffContainer parent, IResource resource, int description) { - super(parent, description); - setLeft(new ResourceNode(resource)); - this.resource = resource; - } - - /* - * Method declared on ITeamNode - */ - public int getChangeDirection() { - return ITeamNode.NO_CHANGE; - } - - /* - * @see ITeamNode#getChangeType() - */ - public int getChangeType() { - return ITeamNode.NO_CHANGE; - } - - public Image getImage() { - return CompareUI.getImage(getType()); - } - - public String getName() { - return resource.getName(); - } - - /** - * Returns the resource underlying this diff node. - */ - public IResource getResource() { - return resource; - } - - public String getType() { - return ITypedElement.FOLDER_TYPE; - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangesSection.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangesSection.java new file mode 100644 index 000000000..99652456e --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangesSection.java @@ -0,0 +1,337 @@ +/******************************************************************************* + * 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.ui.synchronize; + +import javax.swing.event.HyperlinkEvent; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.team.core.ITeamStatus; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.internal.ui.*; +import org.eclipse.team.ui.ISharedImages; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipantPage; +import org.eclipse.team.ui.synchronize.viewers.ISynchronizeModelChangeListener; +import org.eclipse.team.ui.synchronize.viewers.SynchronizeModelElement; +import org.eclipse.ui.forms.events.HyperlinkAdapter; +import org.eclipse.ui.forms.widgets.Hyperlink; +import org.eclipse.ui.part.PageBook; + +/** + * Section shown in a participant page to show the changes for this participant. This + * includes a diff viewer for browsing the changes. + * + * @since 3.0 + */ +public class ChangesSection extends Composite { + + private SubscriberParticipant participant; + private Composite parent; + private SubscriberParticipantPage page; + + /** + * Page book either shows the diff tree viewer if there are changes or + * shows a message to the user if there are no changes that would be + * shown in the tree. + */ + private PageBook changesSectionContainer; + + /** + * Shows message to user is no changes are to be shown in the diff + * tree viewer. + */ + private Composite filteredContainer; + + /** + * Diff tree viewer that shows synchronization changes. This is created + * by the participant. + */ + private Viewer changesViewer; + + /** + * Boolean that indicates whether the error page is being shown. + * This is used to avoid redrawing the error page when new events come in + */ + private boolean showingError; + + /** + * Listen to sync set changes so that we can update message to user and totals. + */ + private ISynchronizeModelChangeListener changedListener = new ISynchronizeModelChangeListener() { + public void modelChanged(SynchronizeModelElement root) { + calculateDescription(); + } + }; + + /** + * Listener registered with the subscriber sync info set which contains + * all out-of-sync resources for the subscriber. + */ + private ISyncInfoSetChangeListener subscriberListener = new ISyncInfoSetChangeListener() { + public void syncInfoSetReset(SyncInfoSet set, IProgressMonitor monitor) { + // Handled by output set listener + } + public void syncInfoChanged(ISyncInfoSetChangeEvent event, IProgressMonitor monitor) { + calculateDescription(); + } + public void syncInfoSetErrors(SyncInfoSet set, ITeamStatus[] errors, IProgressMonitor monitor) { + // Handled by output set listener + } + }; + + /** + * Listener registered with the output sync info set which contains + * only the visible sync info. + */ + private ISyncInfoSetChangeListener outputSetListener = new ISyncInfoSetChangeListener() { + public void syncInfoSetReset(SyncInfoSet set, IProgressMonitor monitor) { + calculateDescription(); + } + public void syncInfoChanged(ISyncInfoSetChangeEvent event, IProgressMonitor monitor) { + // Input changed listener will call calculateDescription() + // The input will then react to output set changes + } + public void syncInfoSetErrors(SyncInfoSet set, ITeamStatus[] errors, IProgressMonitor monitor) { + calculateDescription(); + } + }; + + /** + * Create a changes section on the following page. + * + * @param parent the parent control + * @param page the page showing this section + */ + public ChangesSection(Composite parent, SubscriberParticipantPage page) { + super(parent, SWT.NONE); + this.page = page; + this.participant = page.getParticipant(); + this.parent = parent; + + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + setLayout(layout); + GridData data = new GridData(GridData.FILL_BOTH); + data.grabExcessVerticalSpace = true; + setLayoutData(data); + + changesSectionContainer = new PageBook(this, SWT.NONE); + data = new GridData(GridData.FILL_BOTH); + data.grabExcessHorizontalSpace = true; + data.grabExcessVerticalSpace = true; + changesSectionContainer.setLayoutData(data); + } + + public Composite getComposite() { + return changesSectionContainer; + } + + public void setViewer(Viewer viewer) { + this.changesViewer = viewer; + calculateDescription(); + page.getViewerConfiguration().addInputChangedListener(changedListener); + participant.getSubscriberSyncInfoCollector().getSubscriberSyncInfoSet().addSyncSetChangedListener(subscriberListener); + participant.getSubscriberSyncInfoCollector().getSyncInfoTree().addSyncSetChangedListener(outputSetListener); + } + + private void calculateDescription() { + SyncInfoTree syncInfoTree = participant.getSubscriberSyncInfoCollector().getSyncInfoTree(); + if (syncInfoTree.getErrors().length > 0) { + if (!showingError) { + TeamUIPlugin.getStandardDisplay().asyncExec(new Runnable() { + public void run() { + if (changesSectionContainer.isDisposed()) return; + if(filteredContainer != null) { + filteredContainer.dispose(); + filteredContainer = null; + } + filteredContainer = getErrorComposite(changesSectionContainer); + changesSectionContainer.showPage(filteredContainer); + showingError = true; + } + }); + } + return; + } + + showingError = false; + if(syncInfoTree.size() == 0) { + TeamUIPlugin.getStandardDisplay().asyncExec(new Runnable() { + public void run() { + if (changesSectionContainer.isDisposed()) return; + if(filteredContainer != null) { + filteredContainer.dispose(); + filteredContainer = null; + } + filteredContainer = getEmptyChangesComposite(changesSectionContainer); + changesSectionContainer.showPage(filteredContainer); + } + }); + } else { + TeamUIPlugin.getStandardDisplay().asyncExec(new Runnable() { + public void run() { + if(filteredContainer != null) { + filteredContainer.dispose(); + filteredContainer = null; + } + changesSectionContainer.showPage(changesViewer.getControl()); + } + }); + } + } + + private boolean isThreeWay() { + return page.getParticipant().getSubscriber().getResourceComparator().isThreeWay(); + } + + private Composite getEmptyChangesComposite(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + composite.setLayout(layout); + GridData data = new GridData(GridData.FILL_BOTH); + data.grabExcessVerticalSpace = true; + composite.setLayoutData(data); + + if(! isThreeWay()) { + createDescriptionLabel(composite,Policy.bind("ChangesSection.noChanges", participant.getName())); //$NON-NLS-1$ + return composite; + } + + SyncInfoSet workspace = participant.getSubscriberSyncInfoCollector().getSubscriberSyncInfoSet(); + SyncInfoSet workingSet = participant.getSubscriberSyncInfoCollector().getWorkingSetSyncInfoSet(); + SyncInfoSet filteredSet = participant.getSubscriberSyncInfoCollector().getSyncInfoTree(); + + int changesInWorkspace = workspace.size(); + int changesInWorkingSet = workingSet.size(); + int changesInFilter = filteredSet.size(); + + long outgoingChanges = workingSet.countFor(SyncInfo.OUTGOING, SyncInfo.DIRECTION_MASK); + long incomingChanges = workingSet.countFor(SyncInfo.INCOMING, SyncInfo.DIRECTION_MASK); + + if(changesInFilter == 0 && changesInWorkingSet != 0) { + int mode = participant.getMode(); + final int newMode = outgoingChanges != 0 ? SubscriberParticipant.OUTGOING_MODE : SubscriberParticipant.INCOMING_MODE; + long numChanges = outgoingChanges != 0 ? outgoingChanges : incomingChanges; + StringBuffer text = new StringBuffer(); + text.append(Policy.bind("ChangesSection.filterHides", Utils.modeToString(participant.getMode()))); //$NON-NLS-1$ + if(numChanges > 1) { + text.append(Policy.bind("ChangesSection.filterHidesPlural", Long.toString(numChanges), Utils.modeToString(newMode))); //$NON-NLS-1$ + } else { + text.append(Policy.bind("ChangesSection.filterHidesSingular", Long.toString(numChanges), Utils.modeToString(newMode))); //$NON-NLS-1$ + } + + Label warning = new Label(composite, SWT.NONE); + warning.setImage(TeamUIPlugin.getPlugin().getImage(ISharedImages.IMG_WARNING)); + + Hyperlink link = new Hyperlink(composite, SWT.WRAP); + link.setText(Policy.bind("ChangesSection.filterChange", Utils.modeToString(newMode))); //$NON-NLS-1$ + link.addHyperlinkListener(new HyperlinkAdapter() { + public void linkActivated(HyperlinkEvent e) { + participant.setMode(newMode); + } + }); + link.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + link.setUnderlined(true); + createDescriptionLabel(composite, text.toString()); + } else if(changesInFilter == 0 && changesInWorkingSet == 0 && changesInWorkspace != 0) { + Label warning = new Label(composite, SWT.NONE); + warning.setImage(TeamUIPlugin.getPlugin().getImage(ISharedImages.IMG_WARNING)); + + Hyperlink link = new Hyperlink(composite, SWT.WRAP); + link.setText(Policy.bind("ChangesSection.workingSetRemove")); //$NON-NLS-1$ + link.addHyperlinkListener(new HyperlinkAdapter() { + public void linkActivated(HyperlinkEvent e) { + participant.setWorkingSet(null); + } + }); + link.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + link.setUnderlined(true); + createDescriptionLabel(composite,Policy.bind("ChangesSection.workingSetHiding", Utils.workingSetToString(participant.getWorkingSet(), 50))); //$NON-NLS-1$ + } else { + createDescriptionLabel(composite,Policy.bind("ChangesSection.noChanges", participant.getName())); //$NON-NLS-1$ + } + return composite; + } + + private Label createDescriptionLabel(Composite parent, String text) { + Label description = new Label(parent, SWT.WRAP); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + data.horizontalSpan = 2; + data.widthHint = 100; + description.setLayoutData(data); + description.setText(text); + description.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + return description; + } + + public void dispose() { + super.dispose(); + page.getViewerConfiguration().removeInputChangedListener(changedListener); + participant.getSubscriberSyncInfoCollector().getSubscriberSyncInfoSet().removeSyncSetChangedListener(subscriberListener); + } + + private Composite getErrorComposite(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + composite.setLayout(layout); + GridData data = new GridData(GridData.FILL_BOTH); + data.grabExcessVerticalSpace = true; + composite.setLayoutData(data); + + Hyperlink link = new Hyperlink(composite, SWT.WRAP); + link.setText("Show Errors"); + link.addHyperlinkListener(new HyperlinkAdapter() { + public void linkActivated(HyperlinkEvent e) { + showErrors(); + } + }); + link.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + link.setUnderlined(true); + + link = new Hyperlink(composite, SWT.WRAP); + link.setText("Reset View"); + link.addHyperlinkListener(new HyperlinkAdapter() { + public void linkActivated(HyperlinkEvent e) { + participant.getSubscriberSyncInfoCollector().reset(); + } + }); + link.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + link.setUnderlined(true); + + createDescriptionLabel(composite, "Errors have occurred calculating the synchronization state for {0}" + participant.getName()); + + return composite; + } + + /* private */ void showErrors() { + ITeamStatus[] status = participant.getSubscriberSyncInfoCollector().getSyncInfoTree().getErrors(); + String title = "Errors Populating View"; + if (status.length == 1) { + ErrorDialog.openError(getShell(), title, status[0].getMessage(), status[0]); + } else { + MultiStatus multi = new MultiStatus(TeamUIPlugin.ID, 0, status, "Multiple errors occurred while attempting to populate the view.", null); + ErrorDialog.openError(getShell(), title, null, multi); + } + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ConfigureRefreshScheduleDialog.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ConfigureRefreshScheduleDialog.java new file mode 100644 index 000000000..c4c62f649 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ConfigureRefreshScheduleDialog.java @@ -0,0 +1,197 @@ +package org.eclipse.team.internal.ui.synchronize; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.*; +import org.eclipse.team.internal.ui.dialogs.DetailsDialog; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberRefreshSchedule; +import org.eclipse.team.internal.ui.Policy; + + +public class ConfigureRefreshScheduleDialog extends DetailsDialog { + + private SubscriberRefreshSchedule schedule; + private Button userRefreshOnly; + private Button enableBackgroundRefresh; + private Text time; + private Combo hoursOrSeconds; + + public ConfigureRefreshScheduleDialog(Shell parentShell, SubscriberRefreshSchedule schedule) { + super(parentShell, Policy.bind("ConfigureRefreshScheduleDialog.0", schedule.getParticipant().getName())); //$NON-NLS-1$ + this.schedule = schedule; + } + + private void initializeValues() { + boolean enableBackground = schedule.isEnabled(); + boolean hours = false; + + userRefreshOnly.setSelection(! enableBackground); + enableBackgroundRefresh.setSelection(enableBackground); + + long seconds = schedule.getRefreshInterval(); + if(seconds <= 60) { + seconds = 60; + } + + long minutes = seconds / 60; + + if(minutes >= 60) { + minutes = minutes / 60; + hours = true; + } + hoursOrSeconds.select(hours ? 0 : 1); + time.setText(Long.toString(minutes)); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) + */ + protected void createMainDialogArea(Composite parent) { + Composite area = new Composite(parent, SWT.NONE); + final GridLayout gridLayout = new GridLayout(); + gridLayout.numColumns = 2; + area.setLayout(gridLayout); + area.setLayoutData(new GridData(GridData.FILL_BOTH)); + + { + final Label label = new Label(area, SWT.WRAP); + final GridData gridData = new GridData(GridData.FILL_BOTH); + gridData.horizontalSpan = 2; + gridData.widthHint = 325; + label.setLayoutData(gridData); + label.setText(Policy.bind("ConfigureRefreshScheduleDialog.1", schedule.getParticipant().getName())); //$NON-NLS-1$ + } + { + final Label label = new Label(area, SWT.WRAP); + final GridData gridData = new GridData(GridData.FILL_BOTH); + gridData.horizontalSpan = 2; + gridData.widthHint = 325; + label.setLayoutData(gridData); + label.setText(Policy.bind("ConfigureRefreshScheduleDialog.1a", SubscriberRefreshSchedule.refreshEventAsString(schedule.getLastRefreshEvent()))); //$NON-NLS-1$ + } + { + userRefreshOnly = new Button(area, SWT.RADIO); + final GridData gridData = new GridData(); + gridData.horizontalSpan = 2; + userRefreshOnly.setLayoutData(gridData); + userRefreshOnly.setText(Policy.bind("ConfigureRefreshScheduleDialog.2")); //$NON-NLS-1$ + userRefreshOnly.addSelectionListener(new SelectionListener() { + public void widgetSelected(SelectionEvent e) { + updateEnablements(); + } + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + } + { + enableBackgroundRefresh = new Button(area, SWT.RADIO); + final GridData gridData = new GridData(); + gridData.horizontalSpan = 2; + enableBackgroundRefresh.setLayoutData(gridData); + enableBackgroundRefresh.setText(Policy.bind("ConfigureRefreshScheduleDialog.3")); //$NON-NLS-1$ + enableBackgroundRefresh.addSelectionListener(new SelectionListener() { + public void widgetSelected(SelectionEvent e) { + updateEnablements(); + } + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + } + { + final Composite composite = new Composite(area, SWT.NONE); + final GridData gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_BEGINNING); + gridData.horizontalSpan = 2; + composite.setLayoutData(gridData); + final GridLayout gridLayout_1 = new GridLayout(); + gridLayout_1.numColumns = 3; + composite.setLayout(gridLayout_1); + { + final Label label = new Label(composite, SWT.NONE); + label.setText(Policy.bind("ConfigureRefreshScheduleDialog.4")); //$NON-NLS-1$ + } + { + time = new Text(composite, SWT.BORDER | SWT.RIGHT); + final GridData gridData_1 = new GridData(); + gridData_1.widthHint = 35; + time.setLayoutData(gridData_1); + time.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + updateEnablements(); + } + }); + } + { + hoursOrSeconds = new Combo(composite, SWT.READ_ONLY); + hoursOrSeconds.setItems(new String[] { Policy.bind("ConfigureRefreshScheduleDialog.5"), Policy.bind("ConfigureRefreshScheduleDialog.6") }); //$NON-NLS-1$ //$NON-NLS-2$ + final GridData gridData_1 = new GridData(); + gridData_1.widthHint = 75; + hoursOrSeconds.setLayoutData(gridData_1); + } + } + initializeValues(); + Dialog.applyDialogFont(parent); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#okPressed() + */ + protected void okPressed() { + int hours = hoursOrSeconds.getSelectionIndex(); + long seconds = Long.parseLong(time.getText()); + if(hours == 0) { + seconds = seconds * 3600; + } else { + seconds = seconds * 60; + } + schedule.setRefreshInterval(seconds); + if(schedule.isEnabled() != enableBackgroundRefresh.getSelection()) { + schedule.setEnabled(enableBackgroundRefresh.getSelection(), true /* allow to start */); + } + + // update schedule + schedule.getParticipant().setRefreshSchedule(schedule); + super.okPressed(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.dialogs.DetailsDialog#createDropDownDialogArea(org.eclipse.swt.widgets.Composite) + */ + protected Composite createDropDownDialogArea(Composite parent) { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.dialogs.DetailsDialog#updateEnablements() + */ + protected void updateEnablements() { + try { + long number = Long.parseLong(time.getText()); + if(number <= 0) { + setPageComplete(false); + setErrorMessage(Policy.bind("ConfigureRefreshScheduleDialog.7")); //$NON-NLS-1$ + } else { + setPageComplete(true); + setErrorMessage(null); + } + } catch (NumberFormatException e) { + setPageComplete(false); + setErrorMessage(Policy.bind("ConfigureRefreshScheduleDialog.8")); //$NON-NLS-1$ + } + + time.setEnabled(enableBackgroundRefresh.getSelection()); + hoursOrSeconds.setEnabled(enableBackgroundRefresh.getSelection()); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.dialogs.DetailsDialog#includeDetailsButton() + */ + protected boolean includeDetailsButton() { + return false; + } +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/DiffNodeWorkbenchAdapter.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/DiffNodeWorkbenchAdapter.java new file mode 100644 index 000000000..ea3991bb8 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/DiffNodeWorkbenchAdapter.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * 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.ui.synchronize; + +import org.eclipse.compare.structuremergeviewer.DiffNode; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.team.ui.synchronize.viewers.SynchronizeModelElement; +import org.eclipse.ui.model.IWorkbenchAdapter; + +public class DiffNodeWorkbenchAdapter implements IWorkbenchAdapter { + + /* (non-Javadoc) + * @see org.eclipse.ui.model.IWorkbenchAdapter#getChildren(java.lang.Object) + */ + public Object[] getChildren(Object o) { + DiffNode node = getDiffNode(o); + return node != null ? node.getChildren() : new Object[0]; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.model.IWorkbenchAdapter#getImageDescriptor(java.lang.Object) + */ + public ImageDescriptor getImageDescriptor(Object o) { + DiffNode node = getDiffNode(o); + if(node instanceof SynchronizeModelElement) { + return ((SynchronizeModelElement)node).getImageDescriptor(o); + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.model.IWorkbenchAdapter#getLabel(java.lang.Object) + */ + public String getLabel(Object o) { + DiffNode node = getDiffNode(o); + return node != null ? node.getName() : ""; //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.ui.model.IWorkbenchAdapter#getParent(java.lang.Object) + */ + public Object getParent(Object o) { + DiffNode node = getDiffNode(o); + return node != null ? node.getParent() : null; + } + + /* + * Return a diff node if the input object is a diff node or null otherwise. + */ + private DiffNode getDiffNode(Object element) { + if(element instanceof DiffNode) { + return (DiffNode)element; + } + return null; + } +}
\ No newline at end of file diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/DummyPromptCondition.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/IRefreshEvent.java index 88985f7e7..1fd7579a0 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/DummyPromptCondition.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/IRefreshEvent.java @@ -8,17 +8,29 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.team.tests.ccvs.ui.old; +package org.eclipse.team.internal.ui.synchronize; import org.eclipse.core.resources.IResource; -import org.eclipse.team.internal.ui.dialogs.IPromptCondition; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.team.core.subscribers.Subscriber; +import org.eclipse.team.core.synchronize.SyncInfo; -public class DummyPromptCondition implements IPromptCondition { - public boolean needsPrompt(IResource resource) { - return false; - } - public String promptMessage(IResource resource) { - // this method should never be called - return resource.getName(); - } -} +public interface IRefreshEvent { + public static final int SCHEDULED_REFRESH = 1; + + public static final int USER_REFRESH = 2; + + public int getRefreshType(); + + public Subscriber getSubscriber(); + + public SyncInfo[] getChanges(); + + public long getStartTime(); + + public long getStopTime(); + + public IStatus getStatus(); + + public IResource[] getResources(); +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/IRefreshSubscriberListener.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/IRefreshSubscriberListener.java new file mode 100644 index 000000000..12bb707a5 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/IRefreshSubscriberListener.java @@ -0,0 +1,6 @@ +package org.eclipse.team.internal.ui.synchronize; + +public interface IRefreshSubscriberListener { + public void refreshStarted(IRefreshEvent event); + public void refreshDone(IRefreshEvent event); +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/compare/LocalResourceTypedElement.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/LocalResourceTypedElement.java index f62246052..237a00fea 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/compare/LocalResourceTypedElement.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/LocalResourceTypedElement.java @@ -8,7 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.team.internal.ui.synchronize.compare; +package org.eclipse.team.internal.ui.synchronize; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -28,7 +28,10 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; /** - * LocalResourceTypedElement + * A resource node that is not buffered. Changes made to it are applied directly + * to the underlying resource. + * + * @since 3.0 */ public class LocalResourceTypedElement extends ResourceNode { diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RefreshCompleteDialog.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RefreshCompleteDialog.java new file mode 100644 index 000000000..0b9d71c9e --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RefreshCompleteDialog.java @@ -0,0 +1,297 @@ +/******************************************************************************* + * 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.ui.synchronize; + +import java.lang.reflect.InvocationTargetException; +import org.eclipse.compare.CompareConfiguration; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.*; +import org.eclipse.team.core.subscribers.FilteredSyncInfoCollector; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.internal.ui.*; +import org.eclipse.team.internal.ui.dialogs.DetailsDialog; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; +import org.eclipse.team.ui.synchronize.viewers.TreeViewerAdvisor; +import org.eclipse.team.ui.synchronize.viewers.SynchronizeCompareInput; +import org.eclipse.ui.model.WorkbenchLabelProvider; + +public class RefreshCompleteDialog extends DetailsDialog { + private static final String HEIGHT_KEY = "width-key"; //$NON-NLS-1$ + private final static int RESOURCE_LIST_SIZE = 10; + private static final String WIDTH_KEY = "height-key"; //$NON-NLS-1$ + private FilteredSyncInfoCollector collector; + private SynchronizeCompareInput compareEditorInput; + private IRefreshEvent event; + private SubscriberParticipant participant; + + private Button promptWhenNoChanges; + private Button promptWithChanges; + private IDialogSettings settings; + private SyncInfoTree syncInfoSet = new SyncInfoTree(); + + public RefreshCompleteDialog(Shell parentShell, IRefreshEvent event, SubscriberParticipant participant) { + super(parentShell, Policy.bind("RefreshCompleteDialog.4", participant.getName())); //$NON-NLS-1$ + this.participant = participant; + int shellStyle = getShellStyle(); + setShellStyle(shellStyle | SWT.RESIZE | SWT.MAX); + this.event = event; + setImageKey(DLG_IMG_INFO); + // Set-up a sync info set that contains the resources that where found + // when the refresh occured. + SyncInfoFilter filter = new SyncInfoFilter() { + + public boolean select(SyncInfo info, IProgressMonitor monitor) { + IResource[] resources = getResources(); + for (int i = 0; i < resources.length; i++) { + IResource resource = resources[i]; + if (info.getLocal().equals(resource)) { + return true; + } + } + return false; + } + }; + this.collector = new FilteredSyncInfoCollector( + participant.getSubscriberSyncInfoCollector().getSubscriberSyncInfoSet(), + syncInfoSet, + filter); + IDialogSettings workbenchSettings = TeamUIPlugin.getPlugin().getDialogSettings(); + this.settings = workbenchSettings.getSection("RefreshCompleteDialog");//$NON-NLS-1$ + if (settings == null) { + this.settings = workbenchSettings.addNewSection("RefreshCompleteDialog");//$NON-NLS-1$ + } + } + + /** + * Populate the dialog with the new changes discovered during the refresh + */ + public void initialize() { + this.collector.start(new NullProgressMonitor()); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.window.Window#close() + */ + public boolean close() { + collector.dispose(); + Rectangle bounds = getShell().getBounds(); + settings.put(HEIGHT_KEY, bounds.height); + settings.put(WIDTH_KEY, bounds.width); + return super.close(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite) + */ + protected void createButtonsForButtonBar(Composite parent) { + super.createButtonsForButtonBar(parent); + } + + protected Combo createCombo(Composite parent, int widthChars) { + Combo combo = new Combo(parent, SWT.READ_ONLY); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + GC gc = new GC(combo); + gc.setFont(combo.getFont()); + FontMetrics fontMetrics = gc.getFontMetrics(); + data.widthHint = Dialog.convertWidthInCharsToPixels(fontMetrics, widthChars); + gc.dispose(); + combo.setLayoutData(data); + return combo; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.dialogs.DetailsDialog#createDropDownDialogArea(org.eclipse.swt.widgets.Composite) + */ + protected Composite createDropDownDialogArea(Composite parent) { + try { + CompareConfiguration compareConfig = new CompareConfiguration(); + TreeViewerAdvisor viewerAdvisor = new TreeViewerAdvisor(participant.getId(), syncInfoSet); + compareEditorInput = new SynchronizeCompareInput(compareConfig, viewerAdvisor) { + + public String getTitle() { + return "Resources found during last refresh"; + } + }; + // Preparing the input should be fast since we haven't started the collector + compareEditorInput.run(new NullProgressMonitor()); + // Starting the collector will populate the dialog in the background + initialize(); + } catch (InterruptedException e) { + Utils.handle(e); + } catch (InvocationTargetException e) { + Utils.handle(e); + } + Composite result = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + result.setLayout(layout); + GridData data = new GridData(GridData.FILL_BOTH); + data.grabExcessHorizontalSpace = true; + data.grabExcessVerticalSpace = true; + data.heightHint = 350; + //data.widthHint = 700; + result.setLayoutData(data); + Control c = compareEditorInput.createContents(result); + data = new GridData(GridData.FILL_BOTH); + c.setLayoutData(data); + return result; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.dialogs.DetailsDialog#createMainDialogArea(org.eclipse.swt.widgets.Composite) + */ + protected void createMainDialogArea(Composite parent) { + StringBuffer text = new StringBuffer(); + SyncInfo[] changes = event.getChanges(); + IResource[] resources = event.getResources(); + if (changes.length != 0) { + text.append(Policy.bind("RefreshCompleteDialog.5", Integer.toString(changes.length))); //$NON-NLS-1$ + } else { + text.append(Policy.bind("RefreshCompleteDialog.6")); //$NON-NLS-1$ + } + text.append(Policy.bind("RefreshCompleteDialog.7", Integer.toString(resources.length))); //$NON-NLS-1$ //$NON-NLS-2$ + createLabel(parent, text.toString(), 2); + Table table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); + GridData data = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL); + data.horizontalSpan = 2; + data.widthHint = 200; + table.setLayoutData(data); + /*TableLayout layout = new TableLayout(); + layout.addColumnData(new ColumnWeightData(100, true)); + table.setLayout(layout); + TableColumn col = new TableColumn(table, SWT.NONE); + col.setResizable(true); */ + TableViewer resourceList = new TableViewer(table); + resourceList.setContentProvider(new ArrayContentProvider()); + resourceList.setLabelProvider(new WorkbenchLabelProvider()); + resourceList.setInput(resources); + createLabel(parent, "", 2); //$NON-NLS-1$ + promptWhenNoChanges = new Button(parent, SWT.CHECK); + data = new GridData(GridData.VERTICAL_ALIGN_BEGINNING); + data.horizontalSpan = 2; + promptWhenNoChanges.setLayoutData(data); + promptWithChanges = new Button(parent, SWT.CHECK); + data = new GridData(GridData.VERTICAL_ALIGN_BEGINNING); + data.horizontalSpan = 2; + promptWithChanges.setLayoutData(data); + if (event.getRefreshType() == IRefreshEvent.USER_REFRESH) { + promptWhenNoChanges.setText(Policy.bind(Policy.bind("RefreshCompleteDialog.13"))); //$NON-NLS-1$ + promptWhenNoChanges.setSelection(TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_PROMPT_WHEN_NO_CHANGES)); + promptWithChanges.setText(Policy.bind(Policy.bind("RefreshCompleteDialog.14"))); //$NON-NLS-1$ + promptWithChanges.setSelection(TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_PROMPT_WITH_CHANGES)); + } else { + promptWhenNoChanges.setText(Policy.bind(Policy.bind("RefreshCompleteDialog.15"))); //$NON-NLS-1$ + promptWhenNoChanges.setSelection(TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_BKG_PROMPT_WHEN_NO_CHANGES)); + promptWithChanges.setText(Policy.bind(Policy.bind("RefreshCompleteDialog.16"))); //$NON-NLS-1$ + promptWithChanges.setSelection(TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_BKG_PROMPT_WITH_CHANGES)); + } + Dialog.applyDialogFont(parent); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.dialogs.DetailsDialog#getDetailsButtonLabelHide() + */ + protected String getDetailsButtonLabelHide() { + return Policy.bind("RefreshCompleteDialog.18"); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.dialogs.DetailsDialog#getDetailsButtonLabelShow() + */ + protected String getDetailsButtonLabelShow() { + return Policy.bind("RefreshCompleteDialog.17"); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.window.Window#getInitialSize() + */ + protected Point getInitialSize() { + int width, height; + try { + height = settings.getInt(HEIGHT_KEY); + width = settings.getInt(WIDTH_KEY); + } catch (NumberFormatException e) { + return super.getInitialSize(); + } + Point p = super.getInitialSize(); + return new Point(width, p.y); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.dialogs.DetailsDialog#includeCancelButton() + */ + protected boolean includeCancelButton() { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.dialogs.DetailsDialog#includeDetailsButton() + */ + protected boolean includeDetailsButton() { + return event.getChanges().length != 0; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.dialogs.DetailsDialog#includeErrorMessage() + */ + protected boolean includeErrorMessage() { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#okPressed() + */ + protected void okPressed() { + if (event.getRefreshType() == IRefreshEvent.USER_REFRESH) { + TeamUIPlugin.getPlugin().getPreferenceStore().setValue(IPreferenceIds.SYNCVIEW_VIEW_PROMPT_WHEN_NO_CHANGES, promptWhenNoChanges.getSelection()); + TeamUIPlugin.getPlugin().getPreferenceStore().setValue(IPreferenceIds.SYNCVIEW_VIEW_PROMPT_WITH_CHANGES, promptWithChanges.getSelection()); + } else { + TeamUIPlugin.getPlugin().getPreferenceStore().setValue(IPreferenceIds.SYNCVIEW_VIEW_BKG_PROMPT_WHEN_NO_CHANGES, promptWhenNoChanges.getSelection()); + TeamUIPlugin.getPlugin().getPreferenceStore().setValue(IPreferenceIds.SYNCVIEW_VIEW_BKG_PROMPT_WITH_CHANGES, promptWithChanges.getSelection()); + } + TeamUIPlugin.getPlugin().savePluginPreferences(); + super.okPressed(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.dialogs.DetailsDialog#updateEnablements() + */ + protected void updateEnablements() { + } + + private Label createLabel(Composite parent, String text, int columns) { + Label label = new Label(parent, SWT.WRAP); + label.setText(text); + GridData data = new GridData(); + data.horizontalSpan = columns; + label.setLayoutData(data); + return label; + } + + private IResource[] getResources() { + SyncInfo[] changes = event.getChanges(); + IResource[] resources = new IResource[changes.length]; + for (int i = 0; i < changes.length; i++) { + SyncInfo info = changes[i]; + resources[i] = info.getLocal(); + } + return resources; + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/compare/RemoteResourceTypedElement.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RemoteResourceTypedElement.java index fb55e15e7..edfb92c13 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/compare/RemoteResourceTypedElement.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RemoteResourceTypedElement.java @@ -8,33 +8,29 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.team.internal.ui.synchronize.compare; +package org.eclipse.team.internal.ui.synchronize; import java.io.InputStream; -import org.eclipse.compare.BufferedContent; -import org.eclipse.compare.CompareUI; -import org.eclipse.compare.IEditableContent; -import org.eclipse.compare.ITypedElement; +import org.eclipse.compare.*; import org.eclipse.core.resources.IStorage; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.*; import org.eclipse.swt.graphics.Image; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.IRemoteResource; +import org.eclipse.team.core.synchronize.IResourceVariant; /** * RemoteResourceTypedElement */ public class RemoteResourceTypedElement extends BufferedContent implements ITypedElement, IEditableContent { - private IRemoteResource remote; + private IResourceVariant remote; private IStorage bufferedContents; /** * Creates a new content buffer for the given team node. */ - RemoteResourceTypedElement(IRemoteResource remote) { + public RemoteResourceTypedElement(IResourceVariant remote) { this.remote = remote; } @@ -46,6 +42,10 @@ public class RemoteResourceTypedElement extends BufferedContent implements IType return remote.getName(); } + public String getContentIdentifier() { + return remote.getContentIdentifier(); + } + public String getType() { if (remote.isContainer()) { return ITypedElement.FOLDER_TYPE; @@ -92,13 +92,16 @@ public class RemoteResourceTypedElement extends BufferedContent implements IType * @see BufferedContent#createStream() */ protected InputStream createStream() throws CoreException { + if(bufferedContents == null) { + cacheContents(new NullProgressMonitor()); + } if (bufferedContents != null) { return bufferedContents.getContents(); } return null; } - public IRemoteResource getRemote() { + public IResourceVariant getRemote() { return remote; } @@ -107,7 +110,6 @@ public class RemoteResourceTypedElement extends BufferedContent implements IType * @param monitor */ public void cacheContents(IProgressMonitor monitor) throws TeamException { - bufferedContents = remote.getBufferedStorage(monitor); - + bufferedContents = remote.getStorage(monitor); } }
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeManager.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeManager.java index f658937b8..8a9e9be86 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeManager.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeManager.java @@ -416,12 +416,25 @@ public class SynchronizeManager implements ISynchronizeManager { List participants = (List) synchronizeParticipants.get(id); for (Iterator it2 = participants.iterator(); it2.hasNext(); ) { ParticipantInstance instance = (ParticipantInstance) it2.next(); + + // Participants can opt out of being saved between sessions + if(instance.isParticipantInitialized()) { + ISynchronizeParticipant participant; + try { + participant = instance.getParticipant(); + } catch (TeamException e1) { + continue; + } + if(! participant.isPersistent()) continue; + } - // create the state placeholder for a participant + // Create the state placeholder for a participant IMemento participantNode = xmlMemento.createChild(CTX_PARTICIPANT); participantNode.putString(CTX_ID, instance.getId()); IMemento participantData = participantNode.createChild(CTX_PARTICIPANT_DATA); + // Allow the participant to save it's state. If the participant exists + // but isn't instantiated any loaded state will be re-saved. if(instance.isParticipantInitialized()) { ISynchronizeParticipant participant; try { diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeView.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeView.java index c5c2933cf..0350ddd5d 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeView.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeView.java @@ -13,24 +13,21 @@ package org.eclipse.team.internal.ui.synchronize; import java.util.HashMap; import java.util.Map; +import org.eclipse.core.runtime.jobs.*; import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.IBasicPropertyConstants; import org.eclipse.swt.widgets.Composite; import org.eclipse.team.internal.ui.Policy; +import org.eclipse.team.internal.ui.TeamUIPlugin; +import org.eclipse.team.internal.ui.jobs.JobBusyCursor; import org.eclipse.team.internal.ui.synchronize.actions.SynchronizePageDropDownAction; import org.eclipse.team.ui.TeamUI; -import org.eclipse.team.ui.synchronize.ISynchronizeManager; -import org.eclipse.team.ui.synchronize.ISynchronizeParticipant; -import org.eclipse.team.ui.synchronize.ISynchronizeParticipantListener; -import org.eclipse.team.ui.synchronize.ISynchronizeView; +import org.eclipse.team.ui.synchronize.*; import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.part.IPage; -import org.eclipse.ui.part.IPageBookViewPage; -import org.eclipse.ui.part.MessagePage; -import org.eclipse.ui.part.PageBook; -import org.eclipse.ui.part.PageBookView; +import org.eclipse.ui.part.*; /** * Implements a Synchronize View that contains multiple synchronize participants. @@ -45,15 +42,29 @@ public class SynchronizeView extends PageBookView implements ISynchronizeView, I /** * Map of participants to dummy participant parts (used to close pages) */ - private Map fPageToPart; + private Map fParticipantToPart; /** * Map of parts to participants */ private Map fPartToPage; - + + /** + * Drop down action to switch between participants + */ private SynchronizePageDropDownAction fPageDropDown; + /** + * Half-busy cursor support + */ + private JobBusyCursor halfBusyCursor; + + /** + * Preference key to save + */ + private static final String KEY_LAST_ACTIVE_PARTICIPANT = "lastactiveparticipant"; //$NON-NLS-1$ + private static final String KEY_SETTINGS_SECTION= "SynchronizeViewSettings"; //$NON-NLS-1$ + /* (non-Javadoc) * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) */ @@ -80,7 +91,7 @@ public class SynchronizeView extends PageBookView implements ISynchronizeView, I public ISynchronizeParticipant getParticipant() { return activeParticipant; } - + /* (non-Javadoc) * @see org.eclipse.ui.part.PageBookView#showPageRec(org.eclipse.ui.part.PageBookView.PageRec) */ @@ -109,13 +120,11 @@ public class SynchronizeView extends PageBookView implements ISynchronizeView, I IPage page = pageRecord.page; page.dispose(); pageRecord.dispose(); - - ISynchronizeParticipant participant = (ISynchronizeParticipant)fPartToPage.get(part); + ISynchronizeParticipant participant = (ISynchronizeParticipant) fPartToPage.get(part); participant.removePropertyChangeListener(this); - // empty cross-reference cache fPartToPage.remove(part); - fPageToPart.remove(participant); + fParticipantToPart.remove(participant); } /* (non-Javadoc) @@ -123,13 +132,23 @@ public class SynchronizeView extends PageBookView implements ISynchronizeView, I */ protected PageRec doCreatePage(IWorkbenchPart dummyPart) { SynchronizeViewWorkbenchPart part = (SynchronizeViewWorkbenchPart)dummyPart; - ISynchronizeParticipant participant = part.getConsole(); - IPageBookViewPage page = participant.createPage(this); - initPage(page); - page.createControl(getPageBook()); - participant.addPropertyChangeListener(this); - PageRec rec = new PageRec(dummyPart, page); - return rec; + Object component = part.getPage(); + IPageBookViewPage page = null; + if(component instanceof ISynchronizeParticipant) { + ISynchronizeParticipant participant = (ISynchronizeParticipant)component; + participant.addPropertyChangeListener(this); + page = participant.createPage(this); + } else if(component instanceof IPageBookViewPage) { + page = (IPageBookViewPage)component; + } + + if(page != null) { + initPage(page); + page.createControl(getPageBook()); + PageRec rec = new PageRec(dummyPart, page); + return rec; + } + return null; } /* (non-Javadoc) @@ -144,7 +163,20 @@ public class SynchronizeView extends PageBookView implements ISynchronizeView, I */ public void dispose() { super.dispose(); + + IDialogSettings workbenchSettings = TeamUIPlugin.getPlugin().getDialogSettings(); + if(activeParticipant != null) { + IDialogSettings section = workbenchSettings.getSection(KEY_SETTINGS_SECTION);//$NON-NLS-1$ + if (section == null) { + section = workbenchSettings.addNewSection(KEY_SETTINGS_SECTION); + } + section.put(KEY_LAST_ACTIVE_PARTICIPANT, activeParticipant.getId()); + } + + + halfBusyCursor.dispose(); TeamUI.getSynchronizeManager().removeSynchronizeParticipantListener(this); + } /* (non-Javadoc) @@ -161,21 +193,13 @@ public class SynchronizeView extends PageBookView implements ISynchronizeView, I * @see org.eclipse.team.ui.sync.ISynchronizeParticipantListener#participantsAdded(org.eclipse.team.ui.sync.ISynchronizeParticipant[]) */ public void participantsAdded(final ISynchronizeParticipant[] participants) { - if (isAvailable()) { - Runnable r = new Runnable() { - public void run() { - for (int i = 0; i < participants.length; i++) { - if (isAvailable()) { - ISynchronizeParticipant participant = participants[i]; - SynchronizeViewWorkbenchPart part = new SynchronizeViewWorkbenchPart(participant, getSite()); - fPageToPart.put(participant, part); - fPartToPage.put(part, participant); - partActivated(part); - } - } - } - }; - asyncExec(r); + for (int i = 0; i < participants.length; i++) { + if (isAvailable()) { + ISynchronizeParticipant participant = participants[i]; + SynchronizeViewWorkbenchPart part = new SynchronizeViewWorkbenchPart(participant, getSite()); + fParticipantToPart.put(participant, part); + fPartToPage.put(part, participant); + } } } @@ -189,7 +213,7 @@ public class SynchronizeView extends PageBookView implements ISynchronizeView, I for (int i = 0; i < consoles.length; i++) { if (isAvailable()) { ISynchronizeParticipant console = consoles[i]; - SynchronizeViewWorkbenchPart part = (SynchronizeViewWorkbenchPart)fPageToPart.get(console); + SynchronizeViewWorkbenchPart part = (SynchronizeViewWorkbenchPart)fParticipantToPart.get(console); if (part != null) { partClosed(part); } @@ -212,7 +236,7 @@ public class SynchronizeView extends PageBookView implements ISynchronizeView, I */ public SynchronizeView() { super(); - fPageToPart = new HashMap(); + fParticipantToPart = new HashMap(); fPartToPage = new HashMap(); } @@ -237,7 +261,7 @@ public class SynchronizeView extends PageBookView implements ISynchronizeView, I * @see org.eclipse.team.ui.synchronize.ISynchronizeView#display(org.eclipse.team.ui.synchronize.ISynchronizeParticipant) */ public void display(ISynchronizeParticipant participant) { - SynchronizeViewWorkbenchPart part = (SynchronizeViewWorkbenchPart)fPageToPart.get(participant); + SynchronizeViewWorkbenchPart part = (SynchronizeViewWorkbenchPart)fParticipantToPart.get(participant); if (part != null) { partActivated(part); } @@ -253,8 +277,6 @@ public class SynchronizeView extends PageBookView implements ISynchronizeView, I /** * Registers the given runnable with the display * associated with this view's control, if any. - * - * @see org.eclipse.swt.widgets.Display#asyncExec(java.lang.Runnable) */ public void asyncExec(Runnable r) { if (isAvailable()) { @@ -283,23 +305,55 @@ public class SynchronizeView extends PageBookView implements ISynchronizeView, I createActions(); IToolBarManager tbm= getViewSite().getActionBars().getToolBarManager(); configureToolBar(tbm); + halfBusyCursor = new JobBusyCursor(parent); updateForExistingParticipants(); getViewSite().getActionBars().updateActionBars(); } /** - * Initialize for existing consoles + * Initialize for existing participants */ private void updateForExistingParticipants() { ISynchronizeManager manager = TeamUI.getSynchronizeManager(); // create pages for consoles - ISynchronizeParticipant[] consoles = manager.getSynchronizeParticipants(); - participantsAdded(consoles); - // add as a listener - manager.addSynchronizeParticipantListener(this); + ISynchronizeParticipant[] participants = manager.getSynchronizeParticipants(); + participantsAdded(participants); + // decide which participant to show on startup + if (participants.length > 0) { + ISynchronizeParticipant participantToSelect = participants[0]; + IDialogSettings workbenchSettings = TeamUIPlugin.getPlugin().getDialogSettings(); + IDialogSettings section = workbenchSettings.getSection(KEY_SETTINGS_SECTION);//$NON-NLS-1$ + if (section != null) { + String selectedParticipantId = section.get(KEY_LAST_ACTIVE_PARTICIPANT); + if(selectedParticipantId != null) { + ISynchronizeParticipant[] selectedParticipant = manager.find(selectedParticipantId); + if(selectedParticipant.length > 0) { + participantToSelect = selectedParticipant[0]; + } + } + } + display(participantToSelect); + } + + // add as a listener to update when new participants are added + manager.addSynchronizeParticipantListener(this); } private boolean isAvailable() { return getPageBook() != null && !getPageBook().isDisposed(); } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.WorkbenchPart#getJobChangeListener() + */ + public IJobChangeListener getJobChangeListener() { + return new JobChangeAdapter() { + public void done(IJobChangeEvent event) { + halfBusyCursor.finished(); + } + public void running(IJobChangeEvent event) { + halfBusyCursor.started(); + } + }; + } }
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeViewWorkbenchPart.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeViewWorkbenchPart.java index aa70b136c..cc65485ff 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeViewWorkbenchPart.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeViewWorkbenchPart.java @@ -12,17 +12,14 @@ package org.eclipse.team.internal.ui.synchronize; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; -import org.eclipse.team.ui.synchronize.ISynchronizeParticipant; -import org.eclipse.ui.IPropertyListener; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.*; /** * Fake part to use as keys in page book for synchronize participants */ public class SynchronizeViewWorkbenchPart implements IWorkbenchPart { - private ISynchronizeParticipant participant = null; + private Object page = null; private IWorkbenchPartSite site = null; /* (non-Javadoc) @@ -30,22 +27,22 @@ public class SynchronizeViewWorkbenchPart implements IWorkbenchPart { */ public boolean equals(Object obj) { return (obj instanceof SynchronizeViewWorkbenchPart) && - participant.equals(((SynchronizeViewWorkbenchPart)obj).participant); + page.equals(((SynchronizeViewWorkbenchPart)obj).getPage()); } /* (non-Javadoc) * @see java.lang.Object#hashCode() */ public int hashCode() { - return participant.hashCode(); + return page.hashCode(); } /** * Constructs a part for the given participant that binds to the given * site */ - public SynchronizeViewWorkbenchPart(ISynchronizeParticipant participant, IWorkbenchPartSite site) { - this.participant = participant; + public SynchronizeViewWorkbenchPart(Object page, IWorkbenchPartSite site) { + this.page = page; this.site = site; } @@ -119,7 +116,7 @@ public class SynchronizeViewWorkbenchPart implements IWorkbenchPart { * * @return participant associated with this part */ - protected ISynchronizeParticipant getConsole() { - return participant; + protected Object getPage() { + return page; } }
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/ComparisonCriteriaActionGroup.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/ComparisonCriteriaActionGroup.java deleted file mode 100644 index 516eaf752..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/ComparisonCriteriaActionGroup.java +++ /dev/null @@ -1,157 +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.ui.synchronize.actions; - -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.action.*; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.*; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.ComparisonCriteria; -import org.eclipse.team.internal.ui.TeamUIPlugin; -import org.eclipse.team.internal.ui.Utils; -import org.eclipse.team.internal.ui.synchronize.sets.SubscriberInput; -import org.eclipse.team.ui.TeamUI; -import org.eclipse.team.ui.synchronize.ISynchronizeParticipant; - -/** - * This action group allows the user to choose one or more comparison critera - * to be applied to a comparison - */ -public class ComparisonCriteriaActionGroup extends Action implements IMenuCreator { - - private ComparisonCriteria[] criteria; - private ComparisonCriteriaAction[] actions; - private SubscriberInput input; - private Menu fMenu; - - /** - * Action for filtering by change type. - */ - class ComparisonCriteriaAction extends Action { - private ComparisonCriteria criteria; - public ComparisonCriteriaAction(ComparisonCriteria criteria) { - super(criteria.getName(), Action.AS_RADIO_BUTTON); - this.criteria = criteria; - } - public void run() { - ComparisonCriteriaActionGroup.this.activate(this); - } - public ComparisonCriteria getComparisonCriteria() { - return criteria; - } - } - - public ComparisonCriteriaActionGroup(SubscriberInput input) { - this.input = input; - setMenuCreator(this); - Utils.initAction(this, "action.comparisonCriteria."); //$NON-NLS-1$ - initializeActions(); - } - - public void activate(final ComparisonCriteriaAction activatedAction) { - for (int i = 0; i < actions.length; i++) { - ComparisonCriteriaAction action = actions[i]; - action.setChecked(activatedAction == action); - } - TeamUIPlugin.run(new IRunnableWithProgress() { - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - try { - // when the comparison criteria changes, recalculate the entire sync set based on - // the new input. - input.getSubscriber().setCurrentComparisonCriteria(activatedAction.getComparisonCriteria().getId()); - input.reset(); - } catch (TeamException e) { - throw new InvocationTargetException(e); - } - } - }); - } - - public void initializeActions() { - this.criteria = input.getSubscriber().getComparisonCriterias(); - this.actions = new ComparisonCriteriaAction[criteria.length]; - for (int i = 0; i < criteria.length; i++) { - ComparisonCriteria c = criteria[i]; - actions[i] = new ComparisonCriteriaAction(c); - actions[i].setChecked(c == input.getSubscriber().getCurrentComparisonCriteria()); - } - } - - /* (non-Javadoc) - * @see org.eclipse.ui.texteditor.IUpdate#update() - */ - public void update() { - ISynchronizeParticipant[] pages = TeamUI.getSynchronizeManager().getSynchronizeParticipants(); - setEnabled(pages.length >= 1); - } - - /* (non-Javadoc) - * @see org.eclipse.jface.action.IMenuCreator#dispose() - */ - public void dispose() { - if (fMenu != null) { - fMenu.dispose(); - } - } - - /* (non-Javadoc) - * @see org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets.Menu) - */ - public Menu getMenu(Menu parent) { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets.Control) - */ - public Menu getMenu(Control parent) { - if (fMenu != null) { - fMenu.dispose(); - } - fMenu= new Menu(parent); - ComparisonCriteria currentComparisonCriteria = input.getSubscriber().getCurrentComparisonCriteria(); - for (int i = 0; i < actions.length; i++) { - ComparisonCriteriaAction action = actions[i]; - action.setChecked(action.getComparisonCriteria() == currentComparisonCriteria); - addActionToMenu(fMenu, action); - } - return fMenu; - } - - /* (non-Javadoc) - * @see org.eclipse.jface.action.IAction#run() - */ - public void run() { - // do nothing - this is a menu - } - - public void addActionsToMenuMgr(IMenuManager menu) { - ComparisonCriteria currentComparisonCriteria = input.getSubscriber().getCurrentComparisonCriteria(); - for (int i = 0; i < actions.length; i++) { - ComparisonCriteriaAction action = actions[i]; - action.setChecked(action.getComparisonCriteria() == currentComparisonCriteria); - menu.add(action); - } - } - - protected void addActionToMenu(Menu parent, Action action) { - ActionContributionItem item= new ActionContributionItem(action); - item.fill(parent, -1); - } - - protected void addMenuSeparator() { - new MenuItem(fMenu, SWT.SEPARATOR); - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/ExpandAllAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/ExpandAllAction.java new file mode 100644 index 000000000..0d305b152 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/ExpandAllAction.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * 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.ui.synchronize.actions; + +import java.util.Iterator; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.viewers.*; + + +public class ExpandAllAction extends Action implements ISelectionChangedListener { + + private final AbstractTreeViewer viewer; + + public ExpandAllAction(AbstractTreeViewer viewer) { + this.viewer = viewer; + viewer.addSelectionChangedListener(this); + } + public void run() { + expandAllFromSelection(); + } + + protected void expandAllFromSelection() { + AbstractTreeViewer tree = viewer; + if (tree == null) return; + ISelection selection = tree.getSelection(); + if(! selection.isEmpty()) { + Iterator elements = ((IStructuredSelection)selection).iterator(); + while (elements.hasNext()) { + Object next = elements.next(); + tree.expandToLevel(next, AbstractTreeViewer.ALL_LEVELS); + } + } + } + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent) + */ + public void selectionChanged(SelectionChangedEvent event) { + ISelection selection = event.getSelection(); + if (selection instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection)selection; + setEnabled(!ss.isEmpty()); + return; + } + setEnabled(false); + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/INavigableControl.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/INavigableControl.java deleted file mode 100644 index 14e19b114..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/INavigableControl.java +++ /dev/null @@ -1,25 +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.ui.synchronize.actions; - -public interface INavigableControl { - - /** - * Direction to navigate - */ - final public static int NEXT = 1; - final public static int PREVIOUS = 2; - - /** - * Returns true if at end or beginning. - */ - boolean gotoDifference(int direction); -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/NavigateAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/NavigateAction.java index ce9ebd7f4..6da1e0fcb 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/NavigateAction.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/NavigateAction.java @@ -12,13 +12,16 @@ package org.eclipse.team.internal.ui.synchronize.actions; import org.eclipse.compare.CompareEditorInput; import org.eclipse.compare.ICompareNavigator; +import org.eclipse.compare.internal.INavigatable; import org.eclipse.core.resources.IResource; import org.eclipse.jface.action.Action; import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.team.core.subscribers.SyncInfo; +import org.eclipse.team.core.synchronize.SyncInfo; import org.eclipse.team.internal.ui.Utils; -import org.eclipse.team.ui.synchronize.TeamSubscriberParticipantPage; -import org.eclipse.ui.*; +import org.eclipse.team.ui.synchronize.ISynchronizeView; +import org.eclipse.team.ui.synchronize.viewers.SyncInfoModelElement; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IKeyBindingService; import org.eclipse.ui.actions.ActionFactory; /** @@ -29,20 +32,28 @@ import org.eclipse.ui.actions.ActionFactory; * @since 3.0 */ public class NavigateAction extends Action { - private final int direction; - private TeamSubscriberParticipantPage page; + private final boolean next; + private ISynchronizeView view; + private INavigatable navigator; - public NavigateAction(IViewPart part, TeamSubscriberParticipantPage page, int direction) { - this.page = page; - this.direction = direction; + /** + * Direction to navigate + */ + final public static int NEXT = 1; + final public static int PREVIOUS = 2; + + public NavigateAction(ISynchronizeView view, INavigatable navigator, boolean next) { + this.navigator = navigator; + this.view = view; + this.next = next; - IKeyBindingService kbs = part.getSite().getKeyBindingService(); - if(direction == INavigableControl.NEXT) { + IKeyBindingService kbs = view.getSite().getKeyBindingService(); + if(next) { Utils.initAction(this, "action.navigateNext."); //$NON-NLS-1$ - page.getSite().getActionBars().setGlobalActionHandler(ActionFactory.NEXT.getId(), this); + view.getViewSite().getActionBars().setGlobalActionHandler(ActionFactory.NEXT.getId(), this); } else { Utils.initAction(this, "action.navigatePrevious."); //$NON-NLS-1$ - page.getSite().getActionBars().setGlobalActionHandler(ActionFactory.PREVIOUS.getId(), this); + view.getViewSite().getActionBars().setGlobalActionHandler(ActionFactory.PREVIOUS.getId(), this); } } @@ -52,9 +63,8 @@ public class NavigateAction extends Action { private void navigate() { SyncInfo info = getSyncInfoFromSelection(); - INavigableControl navigable = (INavigableControl)page.getViewer(); if(info == null) { - if(navigable.gotoDifference(direction)) { + if(navigator.gotoDifference(next)) { return; } else { info = getSyncInfoFromSelection(); @@ -63,14 +73,14 @@ public class NavigateAction extends Action { } if(info.getLocal().getType() != IResource.FILE) { - if(! navigable.gotoDifference(direction)) { + if(! navigator.gotoDifference(next)) { info = getSyncInfoFromSelection(); - OpenInCompareAction.openCompareEditor(page, info, true /* keep focus */); + OpenInCompareAction.openCompareEditor(view, view.getParticipant(), info, true /* keep focus */); } return; } - IEditorPart editor = OpenInCompareAction.findOpenCompareEditor(page.getSynchronizeView().getSite(), info.getLocal()); + IEditorPart editor = OpenInCompareAction.findOpenCompareEditor(view.getSite(), info.getLocal()); boolean atEnd = false; CompareEditorInput input; ICompareNavigator navigator; @@ -80,25 +90,28 @@ public class NavigateAction extends Action { input = (CompareEditorInput)editor.getEditorInput(); navigator = (ICompareNavigator)input.getAdapter(ICompareNavigator.class); if(navigator != null) { - if(navigator.selectChange(direction == INavigableControl.NEXT)) { - if(! navigable.gotoDifference(direction)) { + if(navigator.selectChange(next)) { + if(! this.navigator.gotoDifference(next)) { info = getSyncInfoFromSelection(); - OpenInCompareAction.openCompareEditor(page, info, true /* keep focus */); + OpenInCompareAction.openCompareEditor(view, view.getParticipant(), info, true /* keep focus */); } } } } else { // otherwise, select the next change and open a compare editor which will automatically // show the first change. - OpenInCompareAction.openCompareEditor(page, info, true /* keep focus */); + OpenInCompareAction.openCompareEditor(view, view.getParticipant(), info, true /* keep focus */); } } private SyncInfo getSyncInfoFromSelection() { - IStructuredSelection selection = (IStructuredSelection)page.getSynchronizeView().getSite().getPage().getSelection(); + IStructuredSelection selection = (IStructuredSelection)view.getSite().getPage().getSelection(); if(selection == null) return null; Object obj = selection.getFirstElement(); - SyncInfo info = OpenInCompareAction.getSyncInfo(obj); - return info; + if (obj instanceof SyncInfoModelElement) { + return ((SyncInfoModelElement) obj).getSyncInfo(); + } else { + return null; + } } }
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenFileInSystemEditorAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenFileInSystemEditorAction.java index f5f90cc77..8564d3d8e 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenFileInSystemEditorAction.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenFileInSystemEditorAction.java @@ -10,14 +10,11 @@ *******************************************************************************/ package org.eclipse.team.internal.ui.synchronize.actions; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; +import java.util.*; import org.eclipse.core.resources.IResource; import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.team.internal.ui.synchronize.views.SyncSetContentProvider; +import org.eclipse.team.internal.ui.Utils; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.actions.OpenFileAction; @@ -31,19 +28,11 @@ public class OpenFileInSystemEditorAction extends OpenFileAction { * @see org.eclipse.ui.actions.SelectionListenerAction#getSelectedResources() */ protected List getSelectedResources() { - List resources = new ArrayList(); IStructuredSelection selection = getStructuredSelection(); - for (Iterator e = selection.iterator(); e.hasNext();) { - Object next = e.next(); - IResource resource = SyncSetContentProvider.getResource(next); - if(resource != null) { - resources.add(resource); - } - } - return resources; + IResource[] resources = Utils.getResources(selection.toArray()); + return Arrays.asList(resources); } - /* (non-Javadoc) * @see org.eclipse.ui.actions.SelectionListenerAction#getSelectedNonResources() */ diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenInCompareAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenInCompareAction.java index 8ec603520..429f711ed 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenInCompareAction.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenInCompareAction.java @@ -10,32 +10,19 @@ *******************************************************************************/ package org.eclipse.team.internal.ui.synchronize.actions; -import java.lang.reflect.InvocationTargetException; - import org.eclipse.compare.CompareUI; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.action.Action; -import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.core.sync.IRemoteResource; -import org.eclipse.team.internal.ui.Policy; -import org.eclipse.team.internal.ui.TeamUIPlugin; +import org.eclipse.team.core.synchronize.SyncInfo; import org.eclipse.team.internal.ui.Utils; -import org.eclipse.team.internal.ui.actions.TeamAction; -import org.eclipse.team.internal.ui.synchronize.compare.SyncInfoCompareInput; import org.eclipse.team.ui.synchronize.ISynchronizeParticipant; -import org.eclipse.team.ui.synchronize.TeamSubscriberParticipantPage; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IEditorReference; -import org.eclipse.ui.IReusableEditor; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.team.ui.synchronize.ISynchronizeView; +import org.eclipse.team.ui.synchronize.viewers.SyncInfoCompareInput; +import org.eclipse.team.ui.synchronize.viewers.SyncInfoModelElement; +import org.eclipse.ui.*; /** * Action to open a compare editor from a SyncInfo object. @@ -45,24 +32,30 @@ import org.eclipse.ui.IWorkbenchPartSite; */ public class OpenInCompareAction extends Action { - private TeamSubscriberParticipantPage part; + private ISynchronizeView view; + private ISynchronizeParticipant participant; - public OpenInCompareAction(TeamSubscriberParticipantPage part) { - this.part = part; + public OpenInCompareAction(ISynchronizeView view, ISynchronizeParticipant participant) { + this.participant = participant; + this.view = view; Utils.initAction(this, "action.openInCompareEditor."); //$NON-NLS-1$ } public void run() { - ISelection selection = part.getSite().getPage().getSelection(); - Object obj = ((IStructuredSelection)selection).getFirstElement(); - SyncInfo info = getSyncInfo(obj); - if(info != null) { - openCompareEditor(part, info, true /* keep focus */); + ISelection selection = view.getSite().getPage().getSelection(); + if(selection instanceof IStructuredSelection) { + Object obj = ((IStructuredSelection) selection).getFirstElement(); + if (obj instanceof SyncInfoModelElement) { + SyncInfo info = ((SyncInfoModelElement) obj).getSyncInfo(); + if (info != null) { + openCompareEditor(view, participant, info, true); + } + } } } - public static SyncInfoCompareInput openCompareEditor(TeamSubscriberParticipantPage page, SyncInfo info, boolean keepFocus) { - SyncInfoCompareInput input = getCompareInput(page.getParticipant(), info); + public static SyncInfoCompareInput openCompareEditor(IWorkbenchPart page, ISynchronizeParticipant participant, SyncInfo info, boolean keepFocus) { + SyncInfoCompareInput input = getCompareInput(participant, info); if(input != null) { IWorkbenchPage wpage = page.getSite().getPage(); IEditorPart editor = findReusableCompareEditor(wpage); @@ -74,7 +67,6 @@ public class OpenInCompareAction extends Action { wpage.activate(editor); } else { // if editor is currently not open on that input either re-use existing - if (!prefetchFileContents(info)) return null; if(editor != null && editor instanceof IReusableEditor) { CompareUI.reuseCompareEditor(input, (IReusableEditor)editor); wpage.activate(editor); @@ -85,53 +77,19 @@ public class OpenInCompareAction extends Action { } if(keepFocus) { - wpage.activate(page.getSynchronizeView()); + wpage.activate(page); } return input; } return null; } - - /** - * Prefetching the file contents will cache them for use by the compare editor - * so that the compare editor doesn't have to perform file transfers. This will - * make the transfer cancellable. - */ - private static boolean prefetchFileContents(SyncInfo info) { - final IRemoteResource remote = info.getRemote(); - final IRemoteResource base = info.getBase(); - if (remote != null || base != null) { - final boolean[] ok = new boolean[] { true }; - TeamUIPlugin.run(new IRunnableWithProgress() { - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - try { - monitor.beginTask(null, (remote == null ? 0 : 100) + (base == null ? 0 : 100)); - if (remote != null) - remote.getContents(Policy.subMonitorFor(monitor, 100)); - if (base != null) - base.getContents(Policy.subMonitorFor(monitor, 100)); - } catch (TeamException e) { - ok[0] = false; - // The sync viewer will show the error to the user so we need only abort the action - throw new InvocationTargetException(e); - } finally { - // return false if the operation was cancelled - ok[0] = ! monitor.isCanceled(); - monitor.done(); - } - } - }); - return ok[0]; - } - return true; - } /** * Returns a SyncInfoCompareInput instance for the current selection. */ private static SyncInfoCompareInput getCompareInput(ISynchronizeParticipant participant, SyncInfo info) { if (info != null && info.getLocal() instanceof IFile) { - return SyncInfoCompareInput.createInput(participant, info); + return new SyncInfoCompareInput(info); } return null; } @@ -196,8 +154,4 @@ public class OpenInCompareAction extends Action { } return null; } - - public static SyncInfo getSyncInfo(Object obj) { - return (SyncInfo)TeamAction.getAdapter(obj, SyncInfo.class); - } }
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenWithActionGroup.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenWithActionGroup.java index 0720baf62..71a6d58fc 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenWithActionGroup.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenWithActionGroup.java @@ -15,9 +15,9 @@ import org.eclipse.core.resources.IResource; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.team.internal.ui.synchronize.views.SyncSetContentProvider; -import org.eclipse.team.ui.synchronize.TeamSubscriberParticipantPage; -import org.eclipse.ui.IViewPart; +import org.eclipse.team.internal.ui.Utils; +import org.eclipse.team.ui.synchronize.*; +import org.eclipse.team.ui.synchronize.subscriber.*; import org.eclipse.ui.actions.ActionGroup; import org.eclipse.ui.actions.OpenWithMenu; import org.eclipse.ui.views.navigator.ResourceNavigatorMessages; @@ -30,22 +30,23 @@ public class OpenWithActionGroup extends ActionGroup { private OpenFileInSystemEditorAction openFileAction; private OpenInCompareAction openInCompareAction; - private TeamSubscriberParticipantPage page; - private IViewPart part; + private SubscriberParticipantPage page; + private ISynchronizeView view; + private ISynchronizeParticipant participant; - public OpenWithActionGroup(TeamSubscriberParticipantPage page) { - this.page = page; - this.part = page.getSynchronizeView(); + public OpenWithActionGroup(ISynchronizeView part, ISynchronizeParticipant participant) { + this.participant = participant; + this.view = part; makeActions(); } protected void makeActions() { - openFileAction = new OpenFileInSystemEditorAction(part.getSite().getPage()); - openInCompareAction = new OpenInCompareAction(page); + openFileAction = new OpenFileInSystemEditorAction(view.getSite().getPage()); + openInCompareAction = new OpenInCompareAction(view, participant); } public void fillContextMenu(IMenuManager menu) { - fillOpenWithMenu(menu, (IStructuredSelection)part.getSite().getPage().getSelection()); + fillOpenWithMenu(menu, (IStructuredSelection)view.getSite().getPage().getSelection()); } /** @@ -60,11 +61,15 @@ public class OpenWithActionGroup extends ActionGroup { if (selection == null || selection.size() != 1) return; Object element = selection.getFirstElement(); - IResource resource = getResource(element); - if (!(resource instanceof IFile)) { + IResource resources[] = Utils.getResources(new Object[] {element}); + IResource resource = null; + if(resources.length == 0) { return; } - + resource = resources[0]; + + if(resource.getType() != IResource.FILE) return; + menu.add(openInCompareAction); if(!((resource.exists()))) { @@ -76,7 +81,7 @@ public class OpenWithActionGroup extends ActionGroup { MenuManager submenu = new MenuManager(ResourceNavigatorMessages.getString("ResourceNavigator.openWith")); //$NON-NLS-1$ - submenu.add(new OpenWithMenu(part.getSite().getPage(), (IFile) resource)); + submenu.add(new OpenWithMenu(view.getSite().getPage(), (IFile) resource)); menu.add(submenu); } @@ -90,10 +95,6 @@ public class OpenWithActionGroup extends ActionGroup { openFileAction.run(); } } - - private IResource getResource(Object obj) { - return SyncSetContentProvider.getResource(obj); - } public void openInCompareEditor() { openInCompareAction.run(); diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/RefactorActionGroup.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/RefactorActionGroup.java index 13930ea8c..63ba14ed7 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/RefactorActionGroup.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/RefactorActionGroup.java @@ -10,9 +10,7 @@ *******************************************************************************/ package org.eclipse.team.internal.ui.synchronize.actions; -import java.util.ArrayList; import java.util.Iterator; -import java.util.List; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IAdaptable; @@ -22,18 +20,10 @@ import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.widgets.Shell; import org.eclipse.team.internal.ui.Policy; -import org.eclipse.team.internal.ui.synchronize.views.SyncSetContentProvider; -import org.eclipse.ui.IActionBars; -import org.eclipse.ui.IKeyBindingService; -import org.eclipse.ui.ISharedImages; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchPartSite; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.actions.ActionGroup; -import org.eclipse.ui.actions.DeleteResourceAction; -import org.eclipse.ui.actions.MoveResourceAction; -import org.eclipse.ui.actions.RenameResourceAction; -import org.eclipse.ui.actions.TextActionHandler; +import org.eclipse.team.internal.ui.Utils; +import org.eclipse.team.ui.synchronize.ISynchronizeView; +import org.eclipse.ui.*; +import org.eclipse.ui.actions.*; /** * This action group is modeled after the class of the same name in @@ -46,10 +36,10 @@ public class RefactorActionGroup extends ActionGroup { private MoveResourceAction moveAction; private RenameResourceAction renameAction; private TextActionHandler textActionHandler; - private IWorkbenchPart part; + private ISynchronizeView view; - public RefactorActionGroup(IWorkbenchPart part) { - this.part = part; + public RefactorActionGroup(ISynchronizeView view) { + this.view = view; makeActions(); } @@ -77,15 +67,7 @@ public class RefactorActionGroup extends ActionGroup { } private IStructuredSelection convertSelection(IStructuredSelection selection) { - List resources = new ArrayList(); - Iterator it = selection.iterator(); - while(it.hasNext()) { - IResource resource = SyncSetContentProvider.getResource(it.next()); - if(resource != null) { - resources.add(resource); - } - } - return new StructuredSelection(resources); + return new StructuredSelection(Utils.getResources(selection.toArray())); } public void fillActionBars(IActionBars actionBars) { @@ -96,7 +78,7 @@ public class RefactorActionGroup extends ActionGroup { protected void makeActions() { // Get the key binding service for registering actions with commands. - final IWorkbenchPartSite site = part.getSite(); + final IWorkbenchPartSite site = view.getSite(); final IKeyBindingService keyBindingService = site.getKeyBindingService(); Shell shell = site.getShell(); @@ -125,7 +107,7 @@ public class RefactorActionGroup extends ActionGroup { } private IStructuredSelection getSelection() { - return (IStructuredSelection)part.getSite().getPage().getSelection(); + return (IStructuredSelection)view.getSite().getPage().getSelection(); } private boolean allResourcesAreOfType(IStructuredSelection selection, int resourceMask) { @@ -140,7 +122,10 @@ public class RefactorActionGroup extends ActionGroup { resource = (IResource)adaptable.getAdapter(IResource.class); } if(resource == null) { - resource = SyncSetContentProvider.getResource(next); + IResource[] r = Utils.getResources(new Object[] {next}); + if(r.length == 1) { + resource = r[0]; + } } if (resource == null || (resource.getType() & resourceMask) == 0) { return false; diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/RefreshAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/RefreshAction.java deleted file mode 100644 index 9f7dfb26b..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/RefreshAction.java +++ /dev/null @@ -1,100 +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.ui.synchronize.actions; - -import java.lang.reflect.InvocationTargetException; -import java.util.*; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Platform; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.TeamSubscriber; -import org.eclipse.team.internal.ui.*; -import org.eclipse.team.internal.ui.jobs.JobStatusHandler; -import org.eclipse.team.internal.ui.jobs.RefreshSubscriberJob; -import org.eclipse.team.internal.ui.synchronize.sets.SubscriberInput; -import org.eclipse.team.internal.ui.synchronize.views.SyncSetContentProvider; -import org.eclipse.team.ui.synchronize.TeamSubscriberParticipant; -import org.eclipse.team.ui.synchronize.actions.SubscriberAction; -import org.eclipse.ui.IWorkbenchPage; - -public class RefreshAction extends Action { - private boolean refreshAll; - private IWorkbenchPage page; - private TeamSubscriberParticipant participant; - - public RefreshAction(IWorkbenchPage page, TeamSubscriberParticipant participant, boolean refreshAll) { - this.participant = participant; - this.page = page; - this.refreshAll = refreshAll; - Utils.initAction(this, "action.refreshWithRemote."); //$NON-NLS-1$ - } - - public void run() { - ISelection selection = page.getSelection(); - if(selection instanceof IStructuredSelection) { - IResource[] resources = getResources((IStructuredSelection)selection); - SubscriberInput input = participant.getInput(); - if (refreshAll || resources.length == 0) { - // If no resources are selected, refresh all the subscriber roots - resources = input.workingSetRoots(); - } - run(resources, participant); - } - } - - private IResource[] getResources(IStructuredSelection selection) { - if(selection == null) { - return new IResource[0]; - } - List resources = new ArrayList(); - Iterator it = selection.iterator(); - while(it.hasNext()) { - IResource resource = SyncSetContentProvider.getResource(it.next()); - if(resource != null) { - resources.add(resource); - } - } - return (IResource[]) resources.toArray(new IResource[resources.size()]); - } - - public static void run(IResource[] resources, TeamSubscriberParticipant participant) { - // Cancel the scheduled background refresh or any other refresh that is happening. - // The scheduled background refresh will restart automatically. - Platform.getJobManager().cancel(RefreshSubscriberJob.getFamily()); - if(TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_BACKGROUND_SYNC)) { - RefreshSubscriberJob job = new RefreshSubscriberJob(Policy.bind("SyncViewRefresh.taskName", participant.getName()), resources, participant.getInput().getSubscriber()); //$NON-NLS-1$ - JobStatusHandler.schedule(job, SubscriberAction.SUBSCRIBER_JOB_TYPE); - } else { - runBlocking(participant.getInput().getSubscriber(), resources); - } - } - - private static void runBlocking(final TeamSubscriber s, final IResource[] resources) { - TeamUIPlugin.run(new IRunnableWithProgress() { - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - try { - monitor.beginTask(null, 100); - s.refresh(resources, IResource.DEPTH_INFINITE, Policy.subMonitorFor(monitor, 100)); - } catch (TeamException e) { - throw new InvocationTargetException(e); - } finally { - monitor.done(); - } - } - }); - } -}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/actions/RemoveSynchronizeParticipantAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/RemoveSynchronizeParticipantAction.java index 9a6fe244e..1ddf87c28 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/actions/RemoveSynchronizeParticipantAction.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/RemoveSynchronizeParticipantAction.java @@ -8,7 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.team.ui.synchronize.actions; +package org.eclipse.team.internal.ui.synchronize.actions; import org.eclipse.jface.action.Action; import org.eclipse.team.internal.ui.Policy; diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/StatusLineContributionGroup.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/StatusLineContributionGroup.java index 2e1f2fa7d..b74a28f53 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/StatusLineContributionGroup.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/StatusLineContributionGroup.java @@ -10,50 +10,56 @@ *******************************************************************************/ package org.eclipse.team.internal.ui.synchronize.actions; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.action.IStatusLineManager; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.*; -import org.eclipse.team.core.subscribers.SyncInfo; +import org.eclipse.team.core.ITeamStatus; +import org.eclipse.team.core.subscribers.SubscriberSyncInfoCollector; +import org.eclipse.team.core.synchronize.*; import org.eclipse.team.internal.ui.Policy; import org.eclipse.team.internal.ui.TeamUIPlugin; -import org.eclipse.team.internal.ui.synchronize.sets.*; import org.eclipse.team.ui.ISharedImages; -import org.eclipse.team.ui.synchronize.TeamSubscriberParticipant; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IWorkingSet; import org.eclipse.ui.actions.ActionGroup; -public class StatusLineContributionGroup extends ActionGroup implements ISyncSetChangedListener { +public class StatusLineContributionGroup extends ActionGroup implements ISyncInfoSetChangeListener, IPropertyChangeListener { private static final String INCOMING_ID = TeamUIPlugin.ID + "org.eclipse.team.iu.statusline.incoming"; //$NON-NLS-1$ private static final String OUTGOING_ID = TeamUIPlugin.ID + "org.eclipse.team.iu.statusline.outgoing"; //$NON-NLS-1$ private static final String CONFLICTING_ID = TeamUIPlugin.ID + "org.eclipse.team.iu.statusline.conflicting"; //$NON-NLS-1$ private static final String WORKINGSET_ID = TeamUIPlugin.ID + "org.eclipse.team.iu.statusline.workingset"; //$NON-NLS-1$ - private final static int WORKING_SET_FIELD_SIZE = 25; + private static final String TOTALS_ID = TeamUIPlugin.ID + "org.eclipse.team.iu.statusline.totals"; //$NON-NLS-1$ + private final static int TEXT_FIELD_MAX_SIZE = 25; private StatusLineCLabelContribution incoming; private StatusLineCLabelContribution outgoing; private StatusLineCLabelContribution conflicting; private StatusLineCLabelContribution workingSet; + private StatusLineCLabelContribution totalChanges; private Image incomingImage = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_DLG_SYNC_INCOMING).createImage(); private Image outgoingImage = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_DLG_SYNC_OUTGOING).createImage(); private Image conflictingImage = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_DLG_SYNC_CONFLICTING).createImage(); - private SubscriberInput input; - private TeamSubscriberParticipant participant; + private SubscriberSyncInfoCollector collector; + private SubscriberParticipant participant; - public StatusLineContributionGroup(final Shell shell, final WorkingSetFilterActionGroup setGroup, TeamSubscriberParticipant participant) { + public StatusLineContributionGroup(final Shell shell, SubscriberParticipant participant, final WorkingSetFilterActionGroup setGroup) { super(); this.participant = participant; - this.input = participant.getInput(); - this.incoming = createStatusLineContribution(INCOMING_ID, TeamSubscriberParticipant.INCOMING_MODE, "0", incomingImage); //$NON-NLS-1$ - this.outgoing = createStatusLineContribution(OUTGOING_ID, TeamSubscriberParticipant.OUTGOING_MODE, "0", outgoingImage); //$NON-NLS-1$ - this.conflicting = createStatusLineContribution(CONFLICTING_ID, TeamSubscriberParticipant.CONFLICTING_MODE, "0", conflictingImage); //$NON-NLS-1$ - this.workingSet = new StatusLineCLabelContribution(WORKINGSET_ID, 25); + this.collector = participant.getSubscriberSyncInfoCollector(); + this.incoming = createStatusLineContribution(INCOMING_ID, SubscriberParticipant.INCOMING_MODE, "0", incomingImage); //$NON-NLS-1$ + this.outgoing = createStatusLineContribution(OUTGOING_ID, SubscriberParticipant.OUTGOING_MODE, "0", outgoingImage); //$NON-NLS-1$ + this.conflicting = createStatusLineContribution(CONFLICTING_ID, SubscriberParticipant.CONFLICTING_MODE, "0", conflictingImage); //$NON-NLS-1$ + + this.totalChanges = new StatusLineCLabelContribution(TOTALS_ID, TEXT_FIELD_MAX_SIZE); + this.workingSet = new StatusLineCLabelContribution(WORKINGSET_ID, TEXT_FIELD_MAX_SIZE); this.workingSet.setTooltip(Policy.bind("StatisticsPanel.workingSetTooltip")); //$NON-NLS-1$ updateWorkingSetText(); @@ -62,25 +68,26 @@ public class StatusLineContributionGroup extends ActionGroup implements ISyncSet new SelectWorkingSetAction(setGroup, shell).run(); } }); - - input.registerListeners(this); - participant.addPropertyChangeListener(new IPropertyChangeListener() { - public void propertyChange(PropertyChangeEvent event) { - if (event.getProperty().equals(TeamSubscriberParticipant.P_SYNCVIEWPAGE_WORKINGSET)) { - updateWorkingSetText(); - } - } - }); + + // Listen to changes to update the working set + participant.addPropertyChangeListener(this); + + // Listen to changes to update the counts + collector.getSyncInfoTree().addSyncSetChangedListener(this); } + private boolean isThreeWay() { + return participant.getSubscriber().getResourceComparator().isThreeWay(); + } + private void updateWorkingSetText() { IWorkingSet set = participant.getWorkingSet(); if (set == null) { workingSet.setText(Policy.bind("StatisticsPanel.noWorkingSet")); //$NON-NLS-1$ } else { String name = set.getName(); - if (name.length() > WORKING_SET_FIELD_SIZE) { - name = name.substring(0, WORKING_SET_FIELD_SIZE - 3) + "..."; //$NON-NLS-1$ + if (name.length() > TEXT_FIELD_MAX_SIZE) { + name = name.substring(0, TEXT_FIELD_MAX_SIZE - 3) + "..."; //$NON-NLS-1$ } workingSet.setText(name); } @@ -94,30 +101,40 @@ public class StatusLineContributionGroup extends ActionGroup implements ISyncSet } }); item.setText(label); //$NON-NLS-1$ - if (image != null) { - item.setImage(image); - TeamUIPlugin.disposeOnShutdown(image); - } + item.setImage(image); return item; } public void dispose() { - input.deregisterListeners(this); + collector.getSyncInfoTree().removeSyncSetChangedListener(this); + participant.removePropertyChangeListener(this); incomingImage.dispose(); outgoingImage.dispose(); conflictingImage.dispose(); } + public void propertyChange(PropertyChangeEvent event) { + if (event.getProperty().equals(SubscriberParticipant.P_SYNCVIEWPAGE_WORKINGSET)) { + updateWorkingSetText(); + updateCounts(); + } + } + /* * (non-Javadoc) * * @see org.eclipse.team.internal.ui.sync.sets.ISyncSetChangedListener#syncSetChanged(org.eclipse.team.internal.ui.sync.sets.SyncSetChangedEvent) */ - public void syncSetChanged(SyncSetChangedEvent event) { - if (input != null) { - SyncInfoStatistics workspaceSetStats = input.getSubscriberSyncSet().getStatistics(); - SyncInfoStatistics workingSetSetStats = input.getWorkingSetSyncSet().getStatistics(); + public void syncInfoChanged(ISyncInfoSetChangeEvent event, IProgressMonitor monitor) { + updateCounts(); + } + + private void updateCounts() { + if (collector != null) { + SyncInfoSet workspaceSetStats = collector.getSubscriberSyncInfoSet(); + SyncInfoSet workingSetSetStats = collector.getWorkingSetSyncInfoSet(); + final int total = workspaceSetStats.size(); final int workspaceConflicting = (int) workspaceSetStats.countFor(SyncInfo.CONFLICTING, SyncInfo.DIRECTION_MASK); final int workspaceOutgoing = (int) workspaceSetStats.countFor(SyncInfo.OUTGOING, SyncInfo.DIRECTION_MASK); final int workspaceIncoming = (int) workspaceSetStats.countFor(SyncInfo.INCOMING, SyncInfo.DIRECTION_MASK); @@ -127,7 +144,7 @@ public class StatusLineContributionGroup extends ActionGroup implements ISyncSet TeamUIPlugin.getStandardDisplay().asyncExec(new Runnable() { public void run() { - IWorkingSet set = input.getWorkingSet(); + IWorkingSet set = participant.getWorkingSet(); if (set != null) { conflicting.setText(Policy.bind("StatisticsPanel.changeNumbers", new Integer(workingSetConflicting).toString(), new Integer(workspaceConflicting).toString())); //$NON-NLS-1$ incoming.setText(Policy.bind("StatisticsPanel.changeNumbers", new Integer(workingSetIncoming).toString(), new Integer(workspaceIncoming).toString())); //$NON-NLS-1$ @@ -146,6 +163,7 @@ public class StatusLineContributionGroup extends ActionGroup implements ISyncSet outgoing.setTooltip(Policy.bind("StatisticsPanel.numbersTooltip", Policy.bind("StatisticsPanel.outgoing"))); //$NON-NLS-1$ //$NON-NLS-2$ incoming.setTooltip(Policy.bind("StatisticsPanel.numbersTooltip", Policy.bind("StatisticsPanel.incoming"))); //$NON-NLS-1$ //$NON-NLS-2$ } + totalChanges.setText(Policy.bind("StatisticsPanel.numberTotal", Integer.toString(total))); //$NON-NLS-1$ } }); } @@ -159,8 +177,26 @@ public class StatusLineContributionGroup extends ActionGroup implements ISyncSet public void fillActionBars(IActionBars actionBars) { IStatusLineManager mgr = actionBars.getStatusLineManager(); mgr.add(workingSet); - mgr.add(incoming); - mgr.add(outgoing); - mgr.add(conflicting); + if (isThreeWay()) { + mgr.add(incoming); + mgr.add(outgoing); + mgr.add(conflicting); + } else { + mgr.add(totalChanges); + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.ISyncInfoSetChangeListener#syncInfoSetReset(org.eclipse.team.core.subscribers.SyncInfoSet, org.eclipse.core.runtime.IProgressMonitor) + */ + public void syncInfoSetReset(SyncInfoSet set, IProgressMonitor monitor) { + updateCounts(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.ISyncInfoSetChangeListener#syncInfoSetError(org.eclipse.team.core.subscribers.SyncInfoSet, org.eclipse.team.core.ITeamStatus[], org.eclipse.core.runtime.IProgressMonitor) + */ + public void syncInfoSetErrors(SyncInfoSet set, ITeamStatus[] errors, IProgressMonitor monitor) { + // Nothing to do for errors } }
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/SynchronizePageDropDownAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/SynchronizePageDropDownAction.java index 6878b4741..40b468a2e 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/SynchronizePageDropDownAction.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/SynchronizePageDropDownAction.java @@ -10,20 +10,13 @@ *******************************************************************************/ package org.eclipse.team.internal.ui.synchronize.actions; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.ActionContributionItem; -import org.eclipse.jface.action.IMenuCreator; +import org.eclipse.jface.action.*; import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.swt.widgets.*; import org.eclipse.team.internal.ui.TeamUIPlugin; import org.eclipse.team.internal.ui.Utils; import org.eclipse.team.ui.TeamUI; -import org.eclipse.team.ui.synchronize.ISynchronizeParticipant; -import org.eclipse.team.ui.synchronize.ISynchronizeParticipantListener; -import org.eclipse.team.ui.synchronize.ISynchronizeView; +import org.eclipse.team.ui.synchronize.*; import org.eclipse.ui.texteditor.IUpdate; public class SynchronizePageDropDownAction extends Action implements IMenuCreator, ISynchronizeParticipantListener, IUpdate { @@ -43,7 +36,7 @@ public class SynchronizePageDropDownAction extends Action implements IMenuCreato fView= view; Utils.initAction(this, "action.refreshSubscriber."); //$NON-NLS-1$ setMenuCreator(this); - TeamUI.getSynchronizeManager().addSynchronizeParticipantListener(this); + TeamUI.getSynchronizeManager().addSynchronizeParticipantListener(this); update(); } diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/TeamParticipantRefreshAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/TeamParticipantRefreshAction.java new file mode 100644 index 000000000..98b0a5236 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/TeamParticipantRefreshAction.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * 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.ui.synchronize.actions; + +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.team.internal.ui.jobs.RefreshUserNotificationPolicy; +import org.eclipse.team.ui.synchronize.subscriber.RefreshAction; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; +import org.eclipse.ui.IWorkbenchSite; + +/** + * A specialized RefreshAction that extracts the required components from a + * particpant. + */ +public class TeamParticipantRefreshAction extends RefreshAction { + + public TeamParticipantRefreshAction(ISelectionProvider provider, SubscriberParticipant participant, boolean refreshAll) { + super(provider, participant.getName(), participant.getSubscriberSyncInfoCollector(), new RefreshUserNotificationPolicy(participant), refreshAll); + } + + public static void run(IWorkbenchSite site, IResource[] resources, SubscriberParticipant participant) { + run(site, participant.getName(), resources, participant.getSubscriberSyncInfoCollector(), new RefreshUserNotificationPolicy(participant)); + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/ToggleViewLayoutAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/ToggleViewLayoutAction.java deleted file mode 100644 index e7a13b425..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/ToggleViewLayoutAction.java +++ /dev/null @@ -1,50 +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.ui.synchronize.actions; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.swt.SWT; -import org.eclipse.team.internal.ui.Utils; -import org.eclipse.team.ui.synchronize.TeamSubscriberParticipant; - -public class ToggleViewLayoutAction extends Action implements IPropertyChangeListener { - private int layout; - private TeamSubscriberParticipant participant; - - public ToggleViewLayoutAction(TeamSubscriberParticipant participant, int layout) { - super(null, SWT.RADIO); - this.participant = participant; - this.layout = layout; - if(layout == TeamSubscriberParticipant.TABLE_LAYOUT) { - Utils.initAction(this, "action.toggleViewFlat."); //$NON-NLS-1$ - } else { - Utils.initAction(this, "action.toggleViewHierarchical."); //$NON-NLS-1$ - } - setChecked(participant.getLayout() == layout); - participant.addPropertyChangeListener(this); - } - - public void run() { - participant.setLayout(layout); - } - - /* (non-Javadoc) - * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) - */ - public void propertyChange(PropertyChangeEvent event) { - if(event.getProperty().equals(TeamSubscriberParticipant.P_SYNCVIEWPAGE_LAYOUT)) { - Integer newLayout = (Integer)event.getNewValue(); - setChecked(newLayout.intValue() == layout); - } - } -}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/WorkingSetFilterActionGroup.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/WorkingSetFilterActionGroup.java index dd6fd402b..109aa9c56 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/WorkingSetFilterActionGroup.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/WorkingSetFilterActionGroup.java @@ -14,7 +14,7 @@ import org.eclipse.jface.action.*; import org.eclipse.jface.util.*; import org.eclipse.swt.widgets.Shell; import org.eclipse.team.ui.synchronize.ISynchronizeView; -import org.eclipse.team.ui.synchronize.TeamSubscriberParticipant; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; import org.eclipse.ui.*; import org.eclipse.ui.actions.ActionGroup; @@ -43,7 +43,7 @@ public class WorkingSetFilterActionGroup extends ActionGroup { * @param workingSetUpdater property change listener notified when a * working set is set */ - public WorkingSetFilterActionGroup(Shell shell, IPropertyChangeListener workingSetUpdater, ISynchronizeView view, TeamSubscriberParticipant participant) { + public WorkingSetFilterActionGroup(Shell shell, IPropertyChangeListener workingSetUpdater, ISynchronizeView view, SubscriberParticipant participant) { Assert.isNotNull(shell); this.id = participant.toString(); this.workingSetUpdater = workingSetUpdater; diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/compare/SyncInfoCompareInput.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/compare/SyncInfoCompareInput.java deleted file mode 100644 index 928ca46d4..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/compare/SyncInfoCompareInput.java +++ /dev/null @@ -1,206 +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.ui.synchronize.compare; - -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.compare.CompareConfiguration; -import org.eclipse.compare.CompareEditorInput; -import org.eclipse.compare.IContentChangeListener; -import org.eclipse.compare.IContentChangeNotifier; -import org.eclipse.compare.ITypedElement; -import org.eclipse.compare.structuremergeviewer.DiffNode; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.graphics.Image; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.core.sync.IRemoteResource; -import org.eclipse.team.internal.ui.Policy; -import org.eclipse.team.internal.ui.TeamUIPlugin; -import org.eclipse.team.ui.ISharedImages; -import org.eclipse.team.ui.synchronize.ISynchronizeParticipant; - -public class SyncInfoCompareInput extends CompareEditorInput { - - private SyncInfo sync; - private SyncInfoDiffNode node; - private static Image titleImage; - private static ISynchronizeParticipant participant; - - public static SyncInfoCompareInput createInput(ISynchronizeParticipant participant, SyncInfo sync) { - - SyncInfoCompareInput.participant = participant; - // Create the local ITypedElement - ITypedElement localTypedElement = SyncInfoDiffNode.createTypeElement(sync.getLocal(), sync.getKind()); - - // Create the remote ITypedElement - ITypedElement remoteTypedElement = null; - IRemoteResource remoteResource = sync.getRemote(); - if (remoteResource != null) { - remoteTypedElement = SyncInfoDiffNode.createTypeElement(remoteResource); - } - - // Create the base ITypedElement - ITypedElement baseTypedElement = null; - IRemoteResource baseResource = sync.getBase(); - if (baseResource != null) { - baseTypedElement = SyncInfoDiffNode.createTypeElement(baseResource); - } - - return new SyncInfoCompareInput(sync, new SyncInfoDiffNode(baseTypedElement, localTypedElement, remoteTypedElement, sync.getKind())); - } - - private SyncInfoCompareInput(SyncInfo sync, SyncInfoDiffNode diffNode) { - super(new CompareConfiguration()); - this.sync = sync; - this.node = diffNode; - initializeContentChangeListeners(); - } - - private void initializeContentChangeListeners() { - ITypedElement te = node.getLeft(); - if(te instanceof IContentChangeNotifier) { - ((IContentChangeNotifier)te).addContentChangeListener(new IContentChangeListener() { - public void contentChanged(IContentChangeNotifier source) { - try { - saveChanges(new NullProgressMonitor()); - } catch (CoreException e) { - } - } - }); - } - } - - /* (non-Javadoc) - * @see org.eclipse.compare.CompareEditorInput#getTitleImage() - */ - public Image getTitleImage() { - if(titleImage == null) { - titleImage = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_SYNC_VIEW).createImage(); - TeamUIPlugin.disposeOnShutdown(titleImage); - } - return titleImage; - } - - /* (non-Javadoc) - * @see org.eclipse.compare.CompareEditorInput#prepareInput(org.eclipse.core.runtime.IProgressMonitor) - */ - protected Object prepareInput(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - // update the title now that the remote revision number as been fetched from the server - setTitle(getTitle()); - updateLabels(); - try { - node.cacheContents(monitor); - } catch (TeamException e) { - throw new InvocationTargetException(e); - } - return node; - } - - /* (non-Javadoc) - * @see org.eclipse.compare.CompareEditorInput#getTitle() - */ - public String getTitle() { - return Policy.bind("SyncInfoCompareInput.title", participant.getName(), node.getName()); //$NON-NLS-1$ - } - - protected void updateLabels() { - final CompareConfiguration config = getCompareConfiguration(); - final IRemoteResource remote = sync.getRemote(); - final IRemoteResource base = sync.getBase(); - - String localContentId = sync.getLocalContentIdentifier(); - if(localContentId != null) { - config.setLeftLabel(Policy.bind("SyncInfoCompareInput.localLabelExists", localContentId)); //$NON-NLS-1$ - } else { - config.setLeftLabel(Policy.bind("SyncInfoCompareInput.localLabel")); //$NON-NLS-1$ - } - - if(remote != null) { - try { - config.setRightLabel(Policy.bind("SyncInfoCompareInput.remoteLabelExists", remote.getContentIdentifier())); //$NON-NLS-1$ - } catch (TeamException e) { - config.setRightLabel(Policy.bind("SyncInfoCompareInput.remoteLabel")); //$NON-NLS-1$ - } - } else { - config.setRightLabel(Policy.bind("SyncInfoCompareInput.remoteLabel")); //$NON-NLS-1$ - } - - if(base != null) { - try { - config.setAncestorLabel(Policy.bind("SyncInfoCompareInput.baseLabelExists", base.getContentIdentifier())); //$NON-NLS-1$ - } catch (TeamException e) { - config.setAncestorLabel(Policy.bind("SyncInfoCompareInput.baseLabel")); //$NON-NLS-1$ - } - } else { - config.setAncestorLabel(Policy.bind("SyncInfoCompareInput.baseLabel")); //$NON-NLS-1$ - } - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IEditorInput#getImageDescriptor() - */ - public ImageDescriptor getImageDescriptor() { - return TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_SYNC_MODE_FREE); - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IEditorInput#getToolTipText() - */ - public String getToolTipText() { - return Policy.bind("SyncInfoCompareInput.tooltip", participant.getName(), node.getName()); //$NON-NLS-1$ - } - - /* (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals(Object other) { - if(other == this) return true; - if(other instanceof SyncInfoCompareInput) { - return getSyncInfo().equals(((SyncInfoCompareInput)other).getSyncInfo()); - } - return false; - } - - /* (non-Javadoc) - * @see CompareEditorInput#saveChanges(org.eclipse.core.runtime.IProgressMonitor) - */ - public void saveChanges(IProgressMonitor pm) throws CoreException { - super.saveChanges(pm); - if (node != null) { - try { - commit(pm, node); - } finally { - setDirty(false); - } - } - } - - /* - * Recursively walks the diff tree and commits all changes. - */ - private static void commit(IProgressMonitor pm, DiffNode node) throws CoreException { - ITypedElement left= node.getLeft(); - if (left instanceof LocalResourceTypedElement) - ((LocalResourceTypedElement) left).commit(pm); - - ITypedElement right= node.getRight(); - if (right instanceof LocalResourceTypedElement) - ((LocalResourceTypedElement) right).commit(pm); - } - - public SyncInfo getSyncInfo() { - return sync; - } -}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/compare/SyncInfoDiffNode.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/compare/SyncInfoDiffNode.java deleted file mode 100644 index a7f83d7f7..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/compare/SyncInfoDiffNode.java +++ /dev/null @@ -1,77 +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.ui.synchronize.compare; - -import org.eclipse.compare.ITypedElement; -import org.eclipse.compare.structuremergeviewer.DiffNode; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.core.sync.IRemoteResource; -import org.eclipse.team.internal.ui.Policy; - -public class SyncInfoDiffNode extends DiffNode { - - /** - * Create an ITypedElement for the given local resource. The returned ITypedElement - * will prevent edited of outgoing deletions. - */ - public static ITypedElement createTypeElement(IResource resource, final int kind) { - if(resource != null && resource.exists()) { - return new LocalResourceTypedElement(resource) { - public boolean isEditable() { - if(SyncInfo.getDirection(kind) == SyncInfo.OUTGOING && SyncInfo.getChange(kind) == SyncInfo.DELETION) { - return false; - } - return super.isEditable(); - } - }; - } - return null; - } - - /** - * Create an ITypedElement for the given remote resource. The contents for the remote resource - * will be retrieved from the given IStorage which is a local cache used to buffer the remote contents - */ - public static ITypedElement createTypeElement(IRemoteResource remoteResource) { - return new RemoteResourceTypedElement(remoteResource); - } - - /** - * Creates a new diff node. - */ - public SyncInfoDiffNode(ITypedElement base, ITypedElement local, ITypedElement remote, int syncKind) { - super(syncKind, base, local, remote); - } - - /** - * Cache the contents for the base and remote. - * @param monitor - */ - public void cacheContents(IProgressMonitor monitor) throws TeamException { - ITypedElement base = getAncestor(); - ITypedElement remote = getRight(); - int work = Math.min((remote== null ? 0 : 50) + (base == null ? 0 : 50), 10); - monitor.beginTask(null, work); - try { - if (base != null && base instanceof RemoteResourceTypedElement) { - ((RemoteResourceTypedElement)base).cacheContents(Policy.subMonitorFor(monitor, 50)); - } - if (remote != null && remote instanceof RemoteResourceTypedElement) { - ((RemoteResourceTypedElement)remote).cacheContents(Policy.subMonitorFor(monitor, 50)); - } - } finally { - monitor.done(); - } - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SubscriberEventHandler.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SubscriberEventHandler.java deleted file mode 100644 index f57aaff96..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SubscriberEventHandler.java +++ /dev/null @@ -1,307 +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.ui.synchronize.sets; - -import java.util.*; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.BackgroundEventHandler; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.internal.ui.Policy; -import org.eclipse.team.internal.ui.jobs.JobStatusHandler; -import org.eclipse.team.ui.synchronize.actions.SubscriberAction; - -/** - * This handler collects changes and removals to resources and calculates their - * synchronization state in a background job. The result is fed input the SyncSetInput. - * - * Exceptions that occur when the job is processing the events are collected and - * returned as part of the Job's status. - * - * OPTIMIZATION: look into provinding events with multiple resources instead of - * one. - */ -public class SubscriberEventHandler extends BackgroundEventHandler { - // The set that receives notification when the resource synchronization state - // has been calculated by the job. - private SyncSetInputFromSubscriber set; - - // Changes accumulated by the event handler - private List resultCache = new ArrayList(); - - /** - * Internal resource synchronization event. Can contain a result. - */ - class SubscriberEvent extends Event{ - static final int REMOVAL = 1; - static final int CHANGE = 2; - static final int INITIALIZE = 3; - SyncInfo result; - - SubscriberEvent(IResource resource, int type, int depth) { - super(resource, type, depth); - } - public SubscriberEvent( - IResource resource, - int type, - int depth, - SyncInfo result) { - this(resource, type, depth); - this.result = result; - } - public SyncInfo getResult() { - return result; - } - protected String getTypeString() { - switch (getType()) { - case REMOVAL : - return "REMOVAL"; //$NON-NLS-1$ - case CHANGE : - return "CHANGE"; //$NON-NLS-1$ - case INITIALIZE : - return "INITIALIZE"; //$NON-NLS-1$ - default : - return "INVALID"; //$NON-NLS-1$ - } - } - } - - /** - * Create a handler. This will initialize all resources for the subscriber associated with - * the set. - * @param set the subscriber set to feed changes into - */ - public SubscriberEventHandler(SyncSetInputFromSubscriber set) { - this.set = set; - reset(SubscriberEvent.INITIALIZE); - } - - /** - * Schedule the job or process the events now. - */ - public void schedule() { - JobStatusHandler.schedule(getEventHandlerJob(), SubscriberAction.SUBSCRIBER_JOB_TYPE); - } - - /** - * Initialize all resources for the subscriber associated with the set. This will basically recalculate - * all synchronization information for the subscriber. - * @param resource - * @param depth - */ - public void initialize() { - reset(SubscriberEvent.CHANGE); - } - - /** - * Called by a client to indicate that a resource has changed and its synchronization state - * should be recalculated. - * @param resource the changed resource - * @param depth the depth of the change calculation - */ - public void change(IResource resource, int depth) { - queueEvent(new SubscriberEvent(resource, SubscriberEvent.CHANGE, depth)); - } - - /** - * Called by a client to indicate that a resource has been removed and should be removed. The - * removal will propagate to the set. - * @param resource the resource that was removed - */ - public void remove(IResource resource) { - queueEvent( - new SubscriberEvent(resource, SubscriberEvent.REMOVAL, IResource.DEPTH_INFINITE)); - } - - /** - * Collect the calculated synchronization information for the given resource at the given depth. The - * results are added to the provided list. - */ - private void collect( - IResource resource, - int depth, - IProgressMonitor monitor, - List results) - throws TeamException { - - if (resource.getType() != IResource.FILE - && depth != IResource.DEPTH_ZERO) { - IResource[] members = - set.getSubscriber().members(resource); - for (int i = 0; i < members.length; i++) { - collect( - members[i], - depth == IResource.DEPTH_INFINITE - ? IResource.DEPTH_INFINITE - : IResource.DEPTH_ZERO, - monitor, - results); - } - } - - monitor.subTask(Policy.bind("SubscriberEventHandler.2", resource.getFullPath().toString())); //$NON-NLS-1$ - SyncInfo info = set.getSubscriber().getSyncInfo(resource, monitor); - // resource is no longer under the subscriber control - if (info == null) { - results.add( - new SubscriberEvent(resource, SubscriberEvent.REMOVAL, IResource.DEPTH_ZERO)); - } else { - results.add( - new SubscriberEvent(resource, SubscriberEvent.CHANGE, IResource.DEPTH_ZERO, info)); - } - monitor.worked(1); - } - - /** - * Called to initialize to calculate the synchronization information using the optimized subscriber method. For - * subscribers that don't support the optimization, all resources in the subscriber are manually re-calculated. - * @param resources the resources to check - * @param depth the depth - * @param monitor - * @return Event[] the change events - * @throws TeamException - */ - private SubscriberEvent[] getAllOutOfSync( - IResource[] resources, - int depth, - IProgressMonitor monitor) - throws TeamException { - - monitor.beginTask(null, 100); - try { - SyncInfo[] infos = - set.getSubscriber().getAllOutOfSync(resources, depth, Policy.subMonitorFor(monitor, 50)); - - // The subscriber hasn't cached out-of-sync resources. We will have to - // traverse all resources and calculate their state. - if (infos == null) { - List events = new ArrayList(); - IProgressMonitor subMonitor = Policy.subInfiniteMonitorFor(monitor, 50); - subMonitor.beginTask(null, resources.length); - for (int i = 0; i < resources.length; i++) { - collect( - resources[i], - IResource.DEPTH_INFINITE, - subMonitor, - events); - } - return (SubscriberEvent[]) events.toArray(new SubscriberEvent[events.size()]); - // The subscriber has returned the list of out-of-sync resources. - } else { - SubscriberEvent[] events = new SubscriberEvent[infos.length]; - for (int i = 0; i < infos.length; i++) { - SyncInfo info = infos[i]; - events[i] = - new SubscriberEvent(info.getLocal(), SubscriberEvent.CHANGE, depth, info); - } - return events; - } - } finally { - monitor.done(); - } - } - - /** - * Feed the given events to the set. The appropriate method on the set is called - * for each event type. - * @param events - */ - private void dispatchEvents(SubscriberEvent[] events) { - // this will batch the following set changes until endInput is called. - set.getSyncSet().beginInput(); - for (int i = 0; i < events.length; i++) { - SubscriberEvent event = events[i]; - switch (event.getType()) { - case SubscriberEvent.CHANGE : - set.collect(event.getResult()); - break; - case SubscriberEvent.REMOVAL : - if (event.getDepth() == IResource.DEPTH_INFINITE) { - set.getSyncSet().removeAllChildren(event.getResource()); - } else { - set.remove(event.getResource()); - } - break; - } - } - set.getSyncSet().endInput(); - } - - /** - * Initialize all resources for the subscriber associated with the set. This will basically recalculate - * all synchronization information for the subscriber. - * @param type can be Event.CHANGE to recalculate all states or Event.INITIALIZE to perform the - * optimized recalculation if supported by the subscriber. - */ - private void reset(int type) { - IResource[] resources = set.getSubscriber().roots(); - for (int i = 0; i < resources.length; i++) { - queueEvent(new SubscriberEvent(resources[i], type, IResource.DEPTH_INFINITE)); - } - } - - - /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.BackgroundEventHandler#getName() - */ - public String getName() { - return Policy.bind("SubscriberEventHandler.jobName"); //$NON-NLS-1$ - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.BackgroundEventHandler#getErrorsTitle() - */ - public String getErrorsTitle() { - return Policy.bind("SubscriberEventHandler.errors"); //$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) - */ - protected void processEvent(Event event, IProgressMonitor monitor) throws TeamException { - // Cancellation is dangerous because this will leave the sync info in a bad state. - // Purposely not checking - - int type = event.getType(); - switch (type) { - case SubscriberEvent.REMOVAL : - resultCache.add(event); - break; - case SubscriberEvent.CHANGE : - List results = new ArrayList(); - collect( - event.getResource(), - event.getDepth(), - monitor, - results); - resultCache.addAll(results); - break; - case SubscriberEvent.INITIALIZE : - monitor.subTask(Policy.bind("SubscriberEventHandler.2", event.getResource().getFullPath().toString())); //$NON-NLS-1$ - SubscriberEvent[] events = - getAllOutOfSync( - new IResource[] { event.getResource()}, - event.getDepth(), - Policy.subMonitorFor(monitor, 64)); - resultCache.addAll(Arrays.asList(events)); - break; - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.BackgroundEventHandler#dispatchEvents() - */ - protected void dispatchEvents() { - dispatchEvents((SubscriberEvent[]) resultCache.toArray(new SubscriberEvent[resultCache.size()])); - resultCache.clear(); - } -}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SubscriberInput.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SubscriberInput.java deleted file mode 100644 index 854594077..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SubscriberInput.java +++ /dev/null @@ -1,260 +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.ui.synchronize.sets; - -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.ResourcesPlugin; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.ITeamResourceChangeListener; -import org.eclipse.team.core.subscribers.TeamDelta; -import org.eclipse.team.core.subscribers.TeamSubscriber; -import org.eclipse.team.internal.core.Assert; -import org.eclipse.team.internal.ui.TeamUIPlugin; -import org.eclipse.team.ui.TeamUI; -import org.eclipse.team.ui.synchronize.TeamSubscriberParticipant; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter; -import org.eclipse.ui.IWorkingSet; - -/** - * SubscriberInput encapsulates the UI model for synchronization changes associated - * with a TeamSubscriber. - */ -public class SubscriberInput implements IPropertyChangeListener, ITeamResourceChangeListener, IResourceChangeListener { - - /* - * The subscriberInput manages a sync set that contains all of the out-of-sync elements - * of a subscriber. - */ - private SyncSetInputFromSubscriber subscriberSyncSet; - - /* - * The working set sync set is used to constrain the subscriber's resources to - * a smaller workset. - */ - private WorkingSetSyncSetInput workingRootsSet; - - /* - * The filtered set contains the changes after direction and kind filters have been applied - */ - private SyncSetInputFromSyncSet filteredSyncSet; - - /* - * Responsible for calculating changes to a set based on events generated - * in the workbench. - */ - private SubscriberEventHandler eventHandler; - - private TeamSubscriberParticipant participant; - - public SubscriberInput(TeamSubscriberParticipant participant, TeamSubscriber subscriber) { - this.participant = participant; - Assert.isNotNull(subscriber); - subscriberSyncSet = new SyncSetInputFromSubscriber(subscriber); - workingRootsSet = new WorkingSetSyncSetInput(subscriberSyncSet.getSyncSet()); - filteredSyncSet = new SyncSetInputFromSyncSet(workingRootsSet.getSyncSet()); - eventHandler = new SubscriberEventHandler(subscriberSyncSet); - - TeamUI.addPropertyChangeListener(this); - ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE); - subscriber.addListener(this); - } - - public TeamSubscriber getSubscriber() { - return subscriberSyncSet.getSubscriber(); - } - - public TeamSubscriberParticipant getParticipant() { - return participant; - } - - public SyncSet getFilteredSyncSet() { - return filteredSyncSet.getSyncSet(); - } - - public SyncSet getSubscriberSyncSet() { - return subscriberSyncSet.getSyncSet(); - } - - public SyncSet getWorkingSetSyncSet() { - return workingRootsSet.getSyncSet(); - } - - public SubscriberEventHandler getEventHandler() { - return eventHandler; - } - - public void setFilter(SyncInfoFilter filter, IProgressMonitor monitor) throws TeamException { - filteredSyncSet.setFilter(filter); - filteredSyncSet.reset(monitor); - } - - public void setWorkingSet(IWorkingSet set) { - workingRootsSet.setWorkingSet(set); - } - - public IWorkingSet getWorkingSet() { - return workingRootsSet.getWorkingSet(); - } - - public void dispose() { - eventHandler.shutdown(); - - filteredSyncSet.disconnect(); - workingRootsSet.disconnect(); - subscriberSyncSet.disconnect(); - - getSubscriber().removeListener(this); - ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); - TeamUI.removePropertyChangeListener(this); - } - - public IResource[] workingSetRoots() { - return workingRootsSet.roots(getSubscriber()); - } - - public IResource[] subscriberRoots() { - return getSubscriber().roots(); - } - - /* (non-Javadoc) - * @see IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) - */ - public void propertyChange(PropertyChangeEvent event) { - if (event.getProperty().equals(TeamUI.GLOBAL_IGNORES_CHANGED)) { - try { - reset(); - } catch (TeamException e) { - TeamUIPlugin.log(e); - } - } - } - - public void reset() throws TeamException { - subscriberSyncSet.reset(new NullProgressMonitor()); - workingRootsSet.reset(new NullProgressMonitor()); - filteredSyncSet.reset(new NullProgressMonitor()); - eventHandler.initialize(); - } - - /** - * Process the resource delta - * - * @param delta - */ - private void processDelta(IResourceDelta delta) { - IResource resource = delta.getResource(); - int kind = delta.getKind(); - - if (resource.getType() == IResource.PROJECT) { - // Handle a deleted project - if (((kind & IResourceDelta.REMOVED) != 0)) { - eventHandler.remove(resource); - return; - } - // Handle a closed project - if ((delta.getFlags() & IResourceDelta.OPEN) != 0 && !((IProject)resource).isOpen()) { - eventHandler.remove(resource); - return; - } - // Only interested in projects mapped to the provider - if (!isVisibleProject((IProject)resource)) { - // If the project has any entries in the sync set, remove them - if (getSubscriberSyncSet().hasMembers(resource)) { - eventHandler.remove(resource); - } - return; - } - } - - // If the resource has changed type, remove the old resource handle - // and add the new one - if ((delta.getFlags() & IResourceDelta.TYPE) != 0) { - eventHandler.remove(resource); - eventHandler.change(resource, IResource.DEPTH_INFINITE); - } - - // Check the flags for changes the SyncSet cares about. - // Notice we don't care about MARKERS currently. - int changeFlags = delta.getFlags(); - if ((changeFlags & (IResourceDelta.OPEN | IResourceDelta.CONTENT)) != 0) { - eventHandler.change(resource, IResource.DEPTH_ZERO); - } - - // Check the kind and deal with those we care about - if ((delta.getKind() & (IResourceDelta.REMOVED | IResourceDelta.ADDED)) != 0) { - eventHandler.change(resource, IResource.DEPTH_ZERO); - } - - // Handle changed children . - IResourceDelta[] affectedChildren = - delta.getAffectedChildren(IResourceDelta.CHANGED | IResourceDelta.REMOVED | IResourceDelta.ADDED); - for (int i = 0; i < affectedChildren.length; i++) { - processDelta(affectedChildren[i]); - } - } - - private boolean isVisibleProject(IProject project) { - IResource[] roots = subscriberRoots(); - for (int i = 0; i < roots.length; i++) { - IResource resource = roots[i]; - if (project.getFullPath().isPrefixOf(resource.getFullPath())) { - return true; - } - } - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) - */ - public void resourceChanged(IResourceChangeEvent event) { - processDelta(event.getDelta()); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.ITeamResourceChangeListener#teamResourceChanged(org.eclipse.team.core.sync.TeamDelta[]) - */ - public void teamResourceChanged(TeamDelta[] deltas) { - for (int i = 0; i < deltas.length; i++) { - switch(deltas[i].getFlags()) { - case TeamDelta.SYNC_CHANGED: - eventHandler.change(deltas[i].getResource(), IResource.DEPTH_ZERO); - break; - case TeamDelta.PROVIDER_DECONFIGURED: - eventHandler.remove(deltas[i].getResource()); - break; - case TeamDelta.PROVIDER_CONFIGURED: - eventHandler.change(deltas[i].getResource(), IResource.DEPTH_INFINITE); - break; - } - } - } - - public void registerListeners(ISyncSetChangedListener listener) { - getWorkingSetSyncSet().addSyncSetChangedListener(listener); - getFilteredSyncSet().addSyncSetChangedListener(listener); - getSubscriberSyncSet().addSyncSetChangedListener(listener); - } - - public void deregisterListeners(ISyncSetChangedListener listener) { - getWorkingSetSyncSet().removeSyncSetChangedListener(listener); - getFilteredSyncSet().removeSyncSetChangedListener(listener); - getSubscriberSyncSet().removeSyncSetChangedListener(listener); - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncInfoStatistics.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncInfoStatistics.java deleted file mode 100644 index 6027fba3d..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncInfoStatistics.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.ui.synchronize.sets; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.eclipse.team.core.subscribers.SyncInfo; - -/** - * Counts SyncInfo states and allows for easy querying for different sync states. - */ -public class SyncInfoStatistics { - // {int sync kind -> int number of infos with that sync kind in this sync set} - protected Map stats = new HashMap(); - - /** - * Count this sync kind. Only the type of the sync info is stored. - * @param info the new info - */ - public void add(SyncInfo info) { - // update statistics - Long count = (Long)stats.get(new Integer(info.getKind())); - if(count == null) { - count = new Long(0); - } - stats.put(new Integer(info.getKind()), new Long(count.longValue() + 1)); - } - - /** - * Remove this sync kind. - * @param info the info type to remove - */ - public void remove(SyncInfo info) { - // update stats - Integer kind = new Integer(info.getKind()); - Long count = (Long)stats.get(kind); - if(count == null) { - // error condition, shouldn't be removing if we haven't added yet - // programmer error calling remove before add. - } else { - long newCount = count.intValue() - 1; - if(newCount > 0) { - stats.put(kind, new Long(newCount)); - } else { - stats.remove(kind); - } - } - } - - /** - * Return the count of sync infos for the specified sync kind. A mask can be used to acucmulate - * counts for specific directions or change types. - * To return the number of outgoing changes: - * long outgoingChanges = stats.countFor(SyncInfo.OUTGOING, SyncInfo.DIRECTION_MASK); - * - * @param kind the sync kind for which to return the count - * @param mask the mask applied to the stored sync kind - * @return the number of sync info types added for the specific kind - */ - public long countFor(int kind, int mask) { - if(mask == 0) { - Long count = (Long)stats.get(new Integer(kind)); - return count == null ? 0 : count.longValue(); - } else { - Iterator it = stats.keySet().iterator(); - long count = 0; - while (it.hasNext()) { - Integer key = (Integer) it.next(); - if((key.intValue() & mask) == kind) { - count += ((Long)stats.get(key)).intValue(); - } - } - return count; - } - } - - /** - * Clear the statistics counts. All calls to countFor() will return 0 until new - * sync infos are added. - */ - public void clear() { - stats.clear(); - } - - /** - * For debugging - */ - public String toString() { - StringBuffer out = new StringBuffer(); - Iterator it = stats.keySet().iterator(); - while (it.hasNext()) { - Integer kind = (Integer) it.next(); - out.append(SyncInfo.kindToString(kind.intValue()) + ": " + ((Long)stats.get(kind)) + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ - } - return out.toString(); - } -}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncInfoWorkingSetFilter.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncInfoWorkingSetFilter.java deleted file mode 100644 index 12d9a48c5..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncInfoWorkingSetFilter.java +++ /dev/null @@ -1,127 +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.ui.synchronize.sets; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.core.subscribers.TeamSubscriber; -import org.eclipse.team.internal.ui.TeamUIPlugin; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter; -import org.eclipse.ui.IWorkingSet; - -/** - * WorkingSet filter for a SyncSet. - */ -public class SyncInfoWorkingSetFilter extends SyncInfoFilter { - - private IWorkingSet workingSet; - - /* (non-Javadoc) - * @see org.eclipse.team.ui.sync.SyncInfoFilter#select(org.eclipse.team.core.subscribers.SyncInfo) - */ - public boolean select(SyncInfo info) { - // if there's no set, the resource is included - if (workingSet == null) return true; - return isIncluded(info.getLocal()); - } - - /* - * Answer true if the given resource is included in the working set - */ - private boolean isIncluded(IResource resource) { - // otherwise, if their is a parent of the resource in the set, - // it is included - Object[] elements = workingSet.getElements(); - List result = new ArrayList(); - for (int i = 0; i < elements.length; i++) { - IResource setResource = getResource(elements[i]); - if (isParent(setResource, resource)) { - return true; - } - } - return false; - } - - private IResource getResource(Object object) { - if (object instanceof IResource) { - return (IResource)object; - } else if (object instanceof IAdaptable) { - return (IResource)((IAdaptable)object).getAdapter(IResource.class); - } - return null; - } - - private boolean isParent(IResource parent, IResource child) { - return (parent.getFullPath().isPrefixOf(child.getFullPath())); - } - - public IWorkingSet getWorkingSet() { - return workingSet; - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ui.sync.views.SyncSetInputFromSubscriber#getRoots() - */ - public IResource[] getRoots(TeamSubscriber subscriber) { - IResource[] roots = subscriber.roots(); - if (workingSet == null) return roots; - - // filter the roots by the selected working set - Set result = new HashSet(); - for (int i = 0; i < roots.length; i++) { - IResource resource = roots[i]; - result.addAll(Arrays.asList(getIntersectionWithSet(subscriber, resource))); - } - return (IResource[]) result.toArray(new IResource[result.size()]); - } - - /* - * Answer the intersection between the given resource and it's children - * and the receiver's working set. - */ - private IResource[] getIntersectionWithSet(TeamSubscriber subscriber, IResource resource) { - Object[] elements = workingSet.getElements(); - List result = new ArrayList(); - for (int i = 0; i < elements.length; i++) { - IResource setResource = getResource(elements[i]); - if (setResource != null) { - if (isParent(resource, setResource)) { - try { - if (subscriber.isSupervised(setResource)) { - result.add(setResource); - } - } catch (TeamException e) { - // Log the exception and add the resource to the list - TeamUIPlugin.log(e); - result.add(setResource); - } - } else if (isParent(setResource, resource)) { - result.add(resource); - } - } - } - return (IResource[]) result.toArray(new IResource[result.size()]); - } - /** - * @param workingSet - */ - public void setWorkingSet(IWorkingSet workingSet) { - this.workingSet = workingSet; - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncSet.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncSet.java deleted file mode 100644 index 1b677bede..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncSet.java +++ /dev/null @@ -1,348 +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.ui.synchronize.sets; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.ISafeRunnable; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.internal.ui.TeamUIPlugin; - -/** - * This class keeps track of a set of resources and their associated synchronization - * information. It is optimized so that retrieving out-of-sync children is fast. - */ -public class SyncSet { - // fields used to hold resources of interest - // {IPath -> SyncInfo} - protected Map resources = Collections.synchronizedMap(new HashMap()); - - // {IPath -> Set of deep out of sync child IResources} - // weird thing is that the child set will include the - // parent if the parent is out of sync - protected Map parents = Collections.synchronizedMap(new HashMap()); - - // fields used for change notification - protected SyncSetChangedEvent changes; - protected Set listeners = Collections.synchronizedSet(new HashSet()); - - protected SyncInfoStatistics statistics = new SyncInfoStatistics(); - - public SyncSet() { - resetChanges(); - } - - private void resetChanges() { - changes = new SyncSetChangedEvent(this); - } - - private void fireChanges() { - // Use a synchronized block to ensure that the event we send is static - final SyncSetChangedEvent event; - synchronized(this) { - event = changes; - resetChanges(); - } - // Ensure that the list of listeners is not changed while events are fired. - // Copy the listeners so that addition/removal is not blocked by event listeners - if(event.isEmpty() && ! event.isReset()) return; - ISyncSetChangedListener[] allListeners; - synchronized(listeners) { - allListeners = (ISyncSetChangedListener[]) listeners.toArray(new ISyncSetChangedListener[listeners.size()]); - } - // Fire the events using an ISafeRunnable - for (int i = 0; i < allListeners.length; i++) { - final ISyncSetChangedListener listener = allListeners[i]; - Platform.run(new ISafeRunnable() { - public void handleException(Throwable exception) { - // don't log the exception....it is already being logged in Platform#run - } - public void run() throws Exception { - listener.syncSetChanged(event); - - } - }); - } - } - - /** - * Add a change listener - * @param provider - */ - public void addSyncSetChangedListener(ISyncSetChangedListener listener) { - synchronized(listeners) { - listeners.add(listener); - } - } - - /** - * Remove a change listener - * @param provider - */ - public void removeSyncSetChangedListener(ISyncSetChangedListener listener) { - synchronized(listeners) { - listeners.remove(listener); - } - } - - public synchronized void add(SyncInfo info) { - internalAddSyncInfo(info); - changes.added(info); - IResource local = info.getLocal(); - addToParents(local, local); - } - - private void internalAddSyncInfo(SyncInfo info) { - IResource local = info.getLocal(); - IPath path = local.getFullPath(); - SyncInfo oldSyncInfo = (SyncInfo)resources.put(path, info); - if(oldSyncInfo == null) { - statistics.add(info); - } else { - statistics.remove(oldSyncInfo); - statistics.add(info); - } - } - - protected synchronized void remove(IResource local) { - IPath path = local.getFullPath(); - SyncInfo info = (SyncInfo)resources.remove(path); - changes.removed(local); - statistics.remove(info); - removeFromParents(local, local); - } - - protected synchronized void changed(SyncInfo info) { - internalAddSyncInfo(info); - changes.changed(info); - } - - /** - * Reset the sync set so it is empty - */ - public synchronized void reset() { - resources.clear(); - parents.clear(); - changes.reset(); - statistics.clear(); - } - - private boolean addToParents(IResource resource, IResource parent) { - if (parent.getType() == IResource.ROOT) { - return false; - } - // this flag is used to indicate if the parent was previosuly in the set - boolean addedParent = false; - if (parent.getType() == IResource.FILE) { - // the file is new - addedParent = true; - } else { - Set children = (Set)parents.get(parent.getFullPath()); - if (children == null) { - children = new HashSet(); - parents.put(parent.getFullPath(), children); - // this is a new folder in the sync set - addedParent = true; - } - children.add(resource); - } - // if the parent already existed and the resource is new, record it - if (!addToParents(resource, parent.getParent()) && addedParent) { - changes.addedRoot(parent); - } - return addedParent; - } - - private boolean removeFromParents(IResource resource, IResource parent) { - if (parent.getType() == IResource.ROOT) { - return false; - } - // this flag is used to indicate if the parent was removed from the set - boolean removedParent = false; - if (parent.getType() == IResource.FILE) { - // the file will be removed - removedParent = true; - } else { - Set children = (Set)parents.get(parent.getFullPath()); - if (children != null) { - children.remove(resource); - if (children.isEmpty()) { - parents.remove(parent.getFullPath()); - removedParent = true; - } - } - } - // if the parent wasn't removed and the resource was, record it - if (!removeFromParents(resource, parent.getParent()) && removedParent) { - changes.removedRoot(parent); - } - return removedParent; - } - - /** - * Return the children of the given container who are either out-of-sync or contain - * out-of-sync resources. - * - * @param container - * @return - */ - public synchronized IResource[] members(IResource resource) { - if (resource.getType() == IResource.FILE) return new IResource[0]; - IContainer parent = (IContainer)resource; - if (parent.getType() == IResource.ROOT) return getRoots(parent); - // OPTIMIZE: could be optimized so that we don't traverse all the deep - // children to find the immediate ones. - Set children = new HashSet(); - IPath path = parent.getFullPath(); - Set possibleChildren = (Set)parents.get(path); - if(possibleChildren != null) { - for (Iterator it = possibleChildren.iterator(); it.hasNext();) { - Object next = it.next(); - IResource element = (IResource)next; - IPath childPath = element.getFullPath(); - IResource modelObject = null; - if(childPath.segmentCount() == (path.segmentCount() + 1)) { - modelObject = element; - - } else if (childPath.segmentCount() > path.segmentCount()) { - IContainer childFolder = parent.getFolder(new Path(childPath.segment(path.segmentCount()))); - modelObject = childFolder; - } - if (modelObject != null) { - children.add(modelObject); - } - } - } - return (IResource[]) children.toArray(new IResource[children.size()]); - } - - /** - * Return the out-of-sync descendants of the given resource. If the given resource - * is out of sync, it will be included in the result. - * - * @param container - * @return - */ - public synchronized SyncInfo[] getOutOfSyncDescendants(IResource resource) { - if (resource.getType() == IResource.FILE) { - SyncInfo info = getSyncInfo(resource); - if (info == null) { - return new SyncInfo[0]; - } else { - return new SyncInfo[] { info }; - } - } - IContainer container = (IContainer)resource; - IPath path = container.getFullPath(); - Set children = (Set)parents.get(path); - if (children == null) return new SyncInfo[0]; - List infos = new ArrayList(); - for (Iterator iter = children.iterator(); iter.hasNext();) { - IResource child = (IResource) iter.next(); - SyncInfo info = getSyncInfo(child); - if(info != null) { - infos.add(info); - } else { - TeamUIPlugin.log(IStatus.INFO, "missing sync info: " + child.getFullPath(), null); //$NON-NLS-1$ - } - } - return (SyncInfo[]) infos.toArray(new SyncInfo[infos.size()]); - } - - private IResource[] getRoots(IContainer root) { - Set possibleChildren = parents.keySet(); - Set children = new HashSet(); - for (Iterator it = possibleChildren.iterator(); it.hasNext();) { - Object next = it.next(); - IResource element = ((IWorkspaceRoot)root).findMember((IPath)next); - if (element != null) { - children.add(element.getProject()); - } - } - return (IResource[]) children.toArray(new IResource[children.size()]); - } - - /** - * Return an array of all the resources that are known to be out-of-sync - * @return - */ - public synchronized SyncInfo[] allMembers() { - return (SyncInfo[]) resources.values().toArray(new SyncInfo[resources.size()]); - } - - protected synchronized void removeAllChildren(IResource resource) { - // The parent map contains a set of all out-of-sync children - Set allChildren = (Set)parents.get(resource.getFullPath()); - if (allChildren == null) return; - IResource [] removed = (IResource[]) allChildren.toArray(new IResource[allChildren.size()]); - for (int i = 0; i < removed.length; i++) { - remove(removed[i]); - } - } - - public synchronized SyncInfo getSyncInfo(IResource resource) { - return (SyncInfo)resources.get(resource.getFullPath()); - } - - /** - * This method is invoked by a SyncSetInput provider when the - * provider is starting to provide new input to the SyncSet - */ - /* package */ void beginInput() { - synchronized(this) { - resetChanges(); - } - } - - /** - * This method is invoked by a SyncSetInput provider when the - * provider is done providing new input to the SyncSet - */ - /* package */ void endInput() { - fireChanges(); - } - - public int size() { - return resources.size(); - } - - public SyncInfoStatistics getStatistics() { - return statistics; - } - - /** - * Return wether the given resource has any children in the sync set - * @param resource - * @return - */ - public boolean hasMembers(IResource resource) { - if (resource.getType() == IResource.FILE) return false; - IContainer parent = (IContainer)resource; - if (parent.getType() == IResource.ROOT) return !resources.isEmpty(); - IPath path = parent.getFullPath(); - Set allDescendants = (Set)parents.get(path); - return (allDescendants != null && !allDescendants.isEmpty()); - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncSetChangedEvent.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncSetChangedEvent.java deleted file mode 100644 index 9968d9a3c..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncSetChangedEvent.java +++ /dev/null @@ -1,131 +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.ui.synchronize.sets; - -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -import org.eclipse.core.resources.IResource; -import org.eclipse.team.core.subscribers.SyncInfo; - -/** - * This event keeps track of the changes in a sync set - */ -public class SyncSetChangedEvent { - - private SyncSet set; - - // List that accumulate changes - // SyncInfo - private Set changedResources = new HashSet(); - private Set removedResources = new HashSet(); - private Set addedResources = new HashSet(); - - // IResources - private Set removedRoots = new HashSet(); - private Set addedRoots = new HashSet(); - - private boolean reset = false; - - public SyncSetChangedEvent(SyncSet set) { - super(); - this.set = set; - } - - /* package */ void added(SyncInfo info) { - addedResources.add(info); - } - - /* package */ void removed(IResource resource) { - removedResources.add(resource); - } - - /* package */ void changed(SyncInfo info) { - changedResources.add(info); - } - - public void removedRoot(IResource root) { - if (addedRoots.contains(root)) { - // The root was added and removed which is a no-op - addedRoots.remove(root); - } else { - // check if the root is a child of an existing root - // (in which case it need not be added). - // Also, remove any exisiting roots that are children - // of the new root - for (Iterator iter = removedRoots.iterator(); iter.hasNext();) { - IResource element = (IResource) iter.next(); - // check if the root is already in the list - if (root.equals(element)) return; - if (isParent(root, element)) { - // the root invalidates the current element - iter.remove(); - } else if (isParent(element, root)) { - // the root is a child of an existing element - return; - } - } - removedRoots.add(root); - } - } - - private boolean isParent(IResource root, IResource element) { - return root.getFullPath().isPrefixOf(element.getFullPath()); - } - - public void addedRoot(IResource parent) { - if (removedRoots.contains(parent)) { - // The root was re-added which is a no-op - removedRoots.remove(parent); - } else { - // TODO: May be added underneath another added root - addedRoots.add(parent); - } - - } - - public SyncInfo[] getAddedResources() { - return (SyncInfo[]) addedResources.toArray(new SyncInfo[addedResources.size()]); - } - - public IResource[] getAddedRoots() { - return (IResource[]) addedRoots.toArray(new IResource[addedRoots.size()]); - } - - public SyncInfo[] getChangedResources() { - return (SyncInfo[]) changedResources.toArray(new SyncInfo[changedResources.size()]); - } - - public IResource[] getRemovedResources() { - return (IResource[]) removedResources.toArray(new IResource[removedResources.size()]); - } - - public IResource[] getRemovedRoots() { - return (IResource[]) removedRoots.toArray(new IResource[removedRoots.size()]); - } - - public SyncSet getSet() { - return set; - } - - public void reset() { - reset = true; - } - - public boolean isReset() { - return reset; - } - - public boolean isEmpty() { - return changedResources.isEmpty() && removedResources.isEmpty() && addedResources.isEmpty() && removedRoots.isEmpty() && addedRoots.isEmpty(); - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncSetInput.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncSetInput.java deleted file mode 100644 index 71138ac28..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncSetInput.java +++ /dev/null @@ -1,89 +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.ui.synchronize.sets; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter; - -/** - * This is the superclass for all SyncSet input providers - */ -public abstract class SyncSetInput { - - private SyncSet syncSet = new SyncSet(); - private SyncInfoFilter filter = new SyncInfoFilter(); - - public SyncSet getSyncSet() { - return syncSet; - } - - /** - * This method is invoked from reset to get all the sync information from - * the input source. - */ - protected abstract void fetchInput(IProgressMonitor monitor) throws TeamException; - - /** - * The input is no longer being used. Disconnect it from its source. - */ - public abstract void disconnect(); - - /** - * Reset the input. This will clear the current contents of the sync set and - * obtain the contents from the input source. - */ - public void reset(IProgressMonitor monitor) throws TeamException { - try { - syncSet.beginInput(); - syncSet.reset(); - fetchInput(monitor); - } finally { - getSyncSet().endInput(); - } - } - - /** - * Collect the change in the provided sync info. - */ - protected void collect(SyncInfo info) { - boolean isOutOfSync = filter.select(info); - SyncInfo oldInfo = syncSet.getSyncInfo(info.getLocal()); - boolean wasOutOfSync = oldInfo != null; - if (isOutOfSync) { - if (wasOutOfSync) { - syncSet.changed(info); - } else { - syncSet.add(info); - } - } else if (wasOutOfSync) { - syncSet.remove(info.getLocal()); - } - } - - protected void remove(IResource resource) { - SyncInfo oldInfo = syncSet.getSyncInfo(resource); - boolean wasOutOfSync = oldInfo != null; - if (oldInfo != null) { - syncSet.remove(resource); - } - } - - public SyncInfoFilter getFilter() { - return filter; - } - - public void setFilter(SyncInfoFilter filter) { - this.filter = filter; - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncSetInputFromSubscriber.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncSetInputFromSubscriber.java deleted file mode 100644 index 6832fa24c..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncSetInputFromSubscriber.java +++ /dev/null @@ -1,44 +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.ui.synchronize.sets; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.TeamSubscriber; - -/** - * Records resource synchronization changes from a Team subscriber. The actual changes - * are calculated via the SubscriberEventHandler and stored in this input. - */ -public class SyncSetInputFromSubscriber extends SyncSetInput { - - private TeamSubscriber subscriber; - - public SyncSetInputFromSubscriber(TeamSubscriber subscriber) { - this.subscriber = subscriber; - } - - public void disconnect() { - } - - public TeamSubscriber getSubscriber() { - return subscriber; - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ui.sync.views.SyncSetInput#fetchInput(org.eclipse.core.runtime.IProgressMonitor) - */ - protected void fetchInput(IProgressMonitor monitor) throws TeamException { - // don't calculate changes. The SubscriberEventHandler will fetch the - // input in a job and update this sync set when the changes are - // calculated. - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncSetInputFromSyncSet.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncSetInputFromSyncSet.java deleted file mode 100644 index b5c9536b3..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/SyncSetInputFromSyncSet.java +++ /dev/null @@ -1,81 +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.ui.synchronize.sets; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; - -/** - * Ths class uses the contents of one sync set as the input of another. - */ -public class SyncSetInputFromSyncSet extends SyncSetInput implements ISyncSetChangedListener { - - SyncSet inputSyncSet; - - public SyncSetInputFromSyncSet(SyncSet set) { - this.inputSyncSet = set; - inputSyncSet.addSyncSetChangedListener(this); - } - - public SyncSet getInputSyncSet() { - return inputSyncSet; - } - - public void disconnect() { - if (inputSyncSet == null) return; - inputSyncSet.removeSyncSetChangedListener(this); - inputSyncSet = null; - } - - /* (non-Javadoc) - * @see org.eclipse.team.ccvs.syncviews.views.AbstractSyncSet#initialize(java.lang.String, org.eclipse.core.runtime.IProgressMonitor) - */ - protected void fetchInput(IProgressMonitor monitor) throws TeamException { - if (inputSyncSet == null) return; - SyncInfo[] infos = inputSyncSet.allMembers(); - for (int i = 0; i < infos.length; i++) { - collect(infos[i]); - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.ccvs.syncviews.views.ISyncSetChangedListener#syncSetChanged(org.eclipse.team.ccvs.syncviews.views.SyncSetChangedEvent) - */ - public void syncSetChanged(SyncSetChangedEvent event) { - SyncSet syncSet = getSyncSet(); - try { - syncSet.beginInput(); - if (event.isReset()) { - syncSet.reset(); - } - syncSetChanged(event.getChangedResources()); - syncSetChanged(event.getAddedResources()); - - remove(event.getRemovedResources()); - } finally { - getSyncSet().endInput(); - } - } - - private void syncSetChanged(SyncInfo[] infos) { - for (int i = 0; i < infos.length; i++) { - collect(infos[i]); - } - } - - private void remove(IResource[] resources) { - for (int i = 0; i < resources.length; i++) { - remove(resources[i]); - } - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/WorkingSetSyncSetInput.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/WorkingSetSyncSetInput.java deleted file mode 100644 index 34c42965c..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/WorkingSetSyncSetInput.java +++ /dev/null @@ -1,44 +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.ui.synchronize.sets; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.TeamSubscriber; -import org.eclipse.ui.IWorkingSet; - -public class WorkingSetSyncSetInput extends SyncSetInputFromSyncSet { - - private SyncInfoWorkingSetFilter workingSetFilter = new SyncInfoWorkingSetFilter(); - - public WorkingSetSyncSetInput(SyncSet set) { - super(set); - setFilter(workingSetFilter); - } - - public void setWorkingSet(IWorkingSet workSet) { - workingSetFilter.setWorkingSet(workSet); - try { - reset(new NullProgressMonitor()); - } catch (TeamException e) { - // TODO: ?? - } - } - - public IWorkingSet getWorkingSet() { - return workingSetFilter.getWorkingSet(); - } - - public IResource[] roots(TeamSubscriber subscriber) { - return workingSetFilter.getRoots(subscriber); - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/CompressedFolder.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/CompressedFolder.java deleted file mode 100644 index 56a5e2d5f..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/CompressedFolder.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.ui.synchronize.views; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.eclipse.core.resources.IResource; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.internal.ui.synchronize.sets.SubscriberInput; - -/** - * A compressed folder appears under a project and contains out-of-sync resources - */ -public class CompressedFolder extends SynchronizeViewNode { - - public CompressedFolder( SubscriberInput input, IResource resource) { - super(input, resource); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ui.sync.views.SynchronizeViewNode#getOutOfSyncDescendants() - */ - public SyncInfo[] getChildSyncInfos() { - IResource[] children = getSyncSet().members(getResource()); - List result = new ArrayList(); - for (int i = 0; i < children.length; i++) { - IResource child = children[i]; - SyncInfo info = getSyncSet().getSyncInfo(child); - if (info != null) { - if (child.getType() == IResource.FOLDER) { - // for folders, add all out-of-sync children - // NOTE: the method getOutOfSyncDescendants includes the out-of-sync parent - result.addAll(Arrays.asList(getSyncSet().getOutOfSyncDescendants(child))); - } else { - // for files, just add the info - result.add(info); - } - } - } - return (SyncInfo[]) result.toArray(new SyncInfo[result.size()]); - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/CompressedFolderContentProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/CompressedFolderContentProvider.java deleted file mode 100644 index 92724f462..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/CompressedFolderContentProvider.java +++ /dev/null @@ -1,164 +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.ui.synchronize.views; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.jface.viewers.AbstractTreeViewer; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.internal.ui.synchronize.sets.SubscriberInput; -import org.eclipse.team.internal.ui.synchronize.sets.SyncSetChangedEvent; - -/** - * The contents provider compressed in-sync folder paths - */ -public class CompressedFolderContentProvider extends SyncSetTreeContentProvider { - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ui.sync.views.SyncSetContentProvider#handleResourceAdditions(org.eclipse.team.internal.ui.sync.views.SyncSetChangedEvent) - */ - protected void handleResourceAdditions(SyncSetChangedEvent event) { - AbstractTreeViewer tree = getTreeViewer(); - if (tree != null) { - // TODO: For now, refresh any projects with additions - IResource[] roots = event.getAddedRoots(); - refreshProjects(tree, roots); - } else { - super.handleResourceAdditions(event); - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ui.sync.views.SyncSetContentProvider#handleResourceRemovals(org.eclipse.team.internal.ui.sync.views.SyncSetChangedEvent) - */ - protected void handleResourceRemovals(SyncSetChangedEvent event) { - AbstractTreeViewer tree = getTreeViewer(); - if (tree != null) { - // TODO: For now, refresh any projects with deletions - IResource[] roots = event.getRemovedRoots(); - refreshProjects(tree, roots); - } else { - super.handleResourceRemovals(event); - } - } - - private void refreshProjects(AbstractTreeViewer tree, IResource[] roots) { - if (roots.length == 0) return; - Set projects = new HashSet(); - for (int i = 0; i < roots.length; i++) { - if (roots[i].getType() == IResource.PROJECT) { - // when a project is involved, refresh the whole tree - tree.refresh(); - return; - } - projects.add(getModelObject(roots[i].getProject())); - } - for (Iterator iter = projects.iterator(); iter.hasNext();) { - Object element = (Object) iter.next(); - tree.refresh(element); - } - } - - public Object getParent(Object element) { - if (element instanceof CompressedFolder) { - // The parent of a compressed folder is always the project - return getModelObject(getResource(element).getProject()); - } - Object parent = super.getParent(element); - if (parent instanceof SynchronizeViewNode) { - SyncInfo info = ((SynchronizeViewNode)parent).getSyncInfo(); - if (info == null) { - // The resource is in-sync so return a compressed folder - IResource resource = ((SynchronizeViewNode)parent).getResource(); - if (resource.getType() == IResource.FOLDER) { - return new CompressedFolder((SubscriberInput)viewer.getInput(), resource); - - } - } - } - return parent; - } - - public Object[] getChildren(Object element) { - IResource resource = getResource(element); - if (resource != null) { - if (resource.getType() == IResource.PROJECT) { - return getProjectChildren((IProject)resource); - } else if (resource.getType() == IResource.FOLDER) { - return getFolderChildren(resource); - } - } - return super.getChildren(element); - } - - private Object[] getFolderChildren(IResource resource) { - // Folders will only contain out-of-sync children - IResource[] children = getSyncSet().members(resource); - List result = new ArrayList(); - for (int i = 0; i < children.length; i++) { - IResource child = children[i]; - SyncInfo info = getSyncSet().getSyncInfo(child); - if (info != null) { - result.add(getModelObject(info.getLocal())); - } - } - return (Object[]) result.toArray(new Object[result.size()]); - } - - private Object[] getProjectChildren(IProject project) { - SyncInfo[] outOfSync = getSyncSet().getOutOfSyncDescendants(project); - Set result = new HashSet(); - for (int i = 0; i < outOfSync.length; i++) { - SyncInfo info = outOfSync[i]; - IResource local = info.getLocal(); - if (local.getProjectRelativePath().segmentCount() == 1) { - // If the resource is a child of the project, include it uncompressed - result.add(getModelObject(local)); - } else { - IContainer container = getLowestInSyncParent(local); - if (container.getType() == IResource.FOLDER) { - result.add(getModelObject(container)); - } - } - } - return (Object[]) result.toArray(new Object[result.size()]); - } - - /** - * Return a compressed folder if the provided resource is an in-sync folder. - * Warning: This method will return a compressed folder for any in-sync - * folder, even those that do not contain out-of-sync resources (i.e. those that - * are not visible in the view). - */ - public Object getModelObject(IResource resource) { - if (resource.getType() == IResource.FOLDER && getSyncSet().getSyncInfo(resource) == null) { - return new CompressedFolder(getSubscriberInput(), resource); - } - return super.getModelObject(resource); - } - - private IContainer getLowestInSyncParent(IResource resource) { - if (resource.getType() == IResource.ROOT) return (IContainer)resource; - IContainer parent = resource.getParent(); - if (getSyncSet().getSyncInfo(parent) == null) { - return parent; - } - return getLowestInSyncParent(parent); - } - -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncSetContentProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncSetContentProvider.java deleted file mode 100644 index d7c927961..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncSetContentProvider.java +++ /dev/null @@ -1,316 +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.ui.synchronize.views; - -import java.util.HashSet; -import java.util.Set; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IResource; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.StructuredViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.custom.BusyIndicator; -import org.eclipse.swt.widgets.Control; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.internal.ui.synchronize.sets.ISyncSetChangedListener; -import org.eclipse.team.internal.ui.synchronize.sets.SubscriberInput; -import org.eclipse.team.internal.ui.synchronize.sets.SyncSet; -import org.eclipse.team.internal.ui.synchronize.sets.SyncSetChangedEvent; - -/** - * This class provides the contents for a StructuredViewer using a SyncSet as the model - */ -public abstract class SyncSetContentProvider implements IStructuredContentProvider, ISyncSetChangedListener { - - protected Viewer viewer; - - // parents who need a label update accumulated while handling sync set changes - private Set parentsToUpdate = new HashSet(); - - protected SyncSet getSyncSet() { - SubscriberInput input = getSubscriberInput(); - if (input == null) { - return null; - } - return ((SubscriberInput)input).getFilteredSyncSet(); - } - - protected SubscriberInput getSubscriberInput() { - if(viewer == null || viewer.getControl().isDisposed()) { - return null; - } - return (SubscriberInput)viewer.getInput(); - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) - */ - public void inputChanged(Viewer v, Object oldInput, Object newInput) { - - this.viewer = v; - SubscriberInput oldSubscriberInput = null; - SubscriberInput newSubscriberInput = null; - - if (oldInput instanceof SubscriberInput) { - oldSubscriberInput = (SubscriberInput) oldInput; - } - if (newInput instanceof SubscriberInput) { - newSubscriberInput = (SubscriberInput) newInput; - } - if (oldSubscriberInput != newSubscriberInput) { - if (oldSubscriberInput != null) { - ((SubscriberInput)oldSubscriberInput).getFilteredSyncSet().removeSyncSetChangedListener(this); - } - if (newSubscriberInput != null) { - ((SubscriberInput)newSubscriberInput).getFilteredSyncSet().addSyncSetChangedListener(this); - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) - */ - public abstract Object[] getElements(Object inputElement); - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.IContentProvider#dispose() - */ - public void dispose() { - SubscriberInput input = getSubscriberInput(); - if (input != null) { - input.getFilteredSyncSet().removeSyncSetChangedListener(this); - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.ccvs.syncviews.views.ISyncSetChangedListener#syncSetChanged(org.eclipse.team.ccvs.syncviews.views.SyncSetChangedEvent) - */ - public void syncSetChanged(final SyncSetChangedEvent event) { - final Control ctrl = viewer.getControl(); - if (ctrl != null && !ctrl.isDisposed()) { - ctrl.getDisplay().asyncExec(new Runnable() { - public void run() { - if(! ctrl.isDisposed()) { - BusyIndicator.showWhile(ctrl.getDisplay(), new Runnable() { - public void run() { - handleSyncSetChanges(event); - } - }); - } - } - }); - } - } - - /** - * Update the viewer with the sync-set changes, aditions and removals - * in the given event. This method is invoked from within the UI thread. - * @param event - */ - protected void handleSyncSetChanges(SyncSetChangedEvent event) { - viewer.getControl().setRedraw(false); - if (event.isReset()) { - // On a reset, refresh the entire view - ((StructuredViewer) viewer).refresh(); - } else { - handleResourceChanges(event); - handleResourceRemovals(event); - handleResourceAdditions(event); - updateParentLabels(); - } - viewer.getControl().setRedraw(true); - } - - /** - * Update the viewer for the sync set changes in the provided event. - * This method is invoked by <code>handleSyncSetChanges</code>. - * Subclasses may override. - * @param event - * @see #handleSyncSetChanges(SyncSetChangedEvent) - */ - protected void handleResourceChanges(SyncSetChangedEvent event) { - // Refresh the viewer for each changed resource - SyncInfo[] infos = event.getChangedResources(); - for (int i = 0; i < infos.length; i++) { - IResource local = infos[i].getLocal(); - ((StructuredViewer) viewer).refresh(getModelObject(local), true); - updateParentLabels(local); - } - } - - /** - * Update the viewer for the sync set removals in the provided event. - * This method is invoked by <code>handleSyncSetChanges</code>. - * Subclasses may override. - * @param event - */ - protected void handleResourceRemovals(SyncSetChangedEvent event) { - // Update the viewer for each removed resource - IResource[] removed = event.getRemovedRoots(); - for (int i = 0; i < removed.length; i++) { - IResource resource = removed[i]; - ((StructuredViewer) viewer).refresh(getModelObject(resource)); - updateParentLabels(resource); - } - } - - /** - * Update the viewer for the sync set additions in the provided event. - * This method is invoked by <code>handleSyncSetChanges</code>. - * Subclasses may override. - * @param event - */ - protected void handleResourceAdditions(SyncSetChangedEvent event) { - // Update the viewer for each of the added resource's parents - IResource[] added = event.getAddedRoots(); - for (int i = 0; i < added.length; i++) { - IResource resource = added[i]; - ((StructuredViewer) viewer).refresh(getModelObject(resource.getParent())); - updateParentLabels(resource); - } - } - - public StructuredViewer getViewer() { - return (StructuredViewer)viewer; - } - - /** - * Return the children of the given container who are either out-of-sync or contain - * out-of-sync resources. - */ - public Object[] members(IResource resource) { - IResource[] resources = getSubscriberInput().getFilteredSyncSet().members(resource); - Object[] result = new Object[resources.length]; - for (int i = 0; i < resources.length; i++) { - IResource child = resources[i]; - result[i] = getModelObject(child); - } - return result; - } - - /** - * Return the SyncInfo for the given model object that was returned by - * SyncSet#members(IResource). If syncSet is null, then the - * sync info will also be null. - * - * @param element - * @return - */ - public static SyncInfo getSyncInfo(Object element) { - if (element instanceof SyncInfo) { - return ((SyncInfo) element); - } else if (element instanceof SynchronizeViewNode) { - SynchronizeViewNode syncResource = (SynchronizeViewNode)element; - return syncResource.getSyncInfo(); - } - throw new NullPointerException(); - } - - /** - * Return the IResource for the given model object that was returned by - * SyncSet#members(IResource). Return <code>null</code> if the given - * object does not have a corresponding IResource. - * - * @param element - * @return - */ - public static IResource getResource(Object obj) { - if (obj instanceof SyncInfo) { - return ((SyncInfo) obj).getLocal(); - } else if (obj instanceof SynchronizeViewNode) { - return ((SynchronizeViewNode)obj).getResource(); - } - return null; - } - - /** - * Return the sync kind for the given model object that was returned by - * SyncSet#members(IResource). If syncSet is null, then the - * sync kind for SyncContainers will always be 0. - * - * @param element - * @return - */ - public static int getSyncKind(Object element) { - SyncInfo info = getSyncInfo(element); - if (info != null) { - return info.getKind(); - } - return SyncInfo.IN_SYNC; - } - - /** - * Get the model object (SyncSet, SyncInfo or SyncContainer) that is the - * parent of the given model object. - * - * @param syncSet - * @param object - * @return - */ - public Object getParent(Object object) { - IResource resource = getResource(object); - if (resource == null) return null; - IContainer parent = resource.getParent(); - return getModelObject(parent); - } - - /** - * Return the model object for the given IResource. - * @param resource - */ - public Object getModelObject(IResource resource) { - if (resource.getType() == IResource.ROOT) { - return getSubscriberInput(); - } else { - return new SynchronizeViewNode(getSubscriberInput(), resource); - } - } - - protected Object[] getModelObjects(IResource[] resources) { - Object[] result = new Object[resources.length]; - for (int i = 0; i < resources.length; i++) { - result[i] = getModelObject(resources[i]); - } - return result; - } - - /** - * Forces the viewer to update the labels for parents whose children have changed - * during this round of sync set changes. - */ - protected void updateParentLabels() { - try { - getViewer().update( - parentsToUpdate.toArray(new Object[parentsToUpdate.size()]), - null - ); - } finally { - parentsToUpdate.clear(); - } - } - - /** - * Forces the viewer to update the labels for parents of this element. This - * can be useful when parents labels include information about their children - * that needs updating when a child changes. - * <p> - * This method should only be called while processing sync set changes. - * Changed parents are accumulated and updated at the end of the change processing - */ - protected void updateParentLabels(IResource resource) { - IResource parent = resource.getParent(); - while(parent.getType() != IResource.ROOT) { - parentsToUpdate.add(getModelObject(parent)); - parent = parent.getParent(); - } - } -}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncSetTableContentProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncSetTableContentProvider.java deleted file mode 100644 index 456ba1dce..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncSetTableContentProvider.java +++ /dev/null @@ -1,76 +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.ui.synchronize.views; - -import org.eclipse.core.resources.IResource; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.internal.ui.synchronize.sets.*; - -/** - * This class provides the contents for a TableViewer using a SyncSet as the model - */ -public class SyncSetTableContentProvider extends SyncSetContentProvider { - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) - */ - public Object[] getElements(Object element) { - SyncInfo[] infos = getSyncSet().allMembers(); - return getModelObjects(infos); - } - - public TableViewer getTableViewer() { - if (viewer instanceof TableViewer) { - return (TableViewer)viewer; - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.team.ccvs.syncviews.views.SyncSetContentProvider#handleResourceAdditions(org.eclipse.team.ccvs.syncviews.views.SyncSetChangedEvent) - */ - protected void handleResourceAdditions(SyncSetChangedEvent event) { - TableViewer table = getTableViewer(); - if (table != null) { - SyncInfo[] infos = event.getAddedResources(); - table.add(getModelObjects(infos)); - } else { - super.handleResourceAdditions(event); - } - - } - - /* (non-Javadoc) - * @see org.eclipse.team.ccvs.syncviews.views.SyncSetContentProvider#handleResourceRemovals(org.eclipse.team.ccvs.syncviews.views.SyncSetChangedEvent) - */ - protected void handleResourceRemovals(SyncSetChangedEvent event) { - TableViewer table = getTableViewer(); - if (table != null) { - IResource[] resources = event.getRemovedResources(); - table.remove(getModelObjects(resources)); - } else { - super.handleResourceRemovals(event); - } - } - - protected Object getModelObject(SyncInfo info) { - return getModelObject(info.getLocal()); - } - - protected Object[] getModelObjects(SyncInfo[] infos) { - Object[] resources = new Object[infos.length]; - for (int i = 0; i < resources.length; i++) { - resources[i] = getModelObject(infos[i]); - } - return resources; - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncSetTreeContentProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncSetTreeContentProvider.java deleted file mode 100644 index 45750a41e..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncSetTreeContentProvider.java +++ /dev/null @@ -1,117 +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.ui.synchronize.views; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.jface.viewers.AbstractTreeViewer; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.team.internal.ui.synchronize.sets.SubscriberInput; -import org.eclipse.team.internal.ui.synchronize.sets.SyncSetChangedEvent; - -/** - * This class provides the contents for a AbstractTreeViewer using a SyncSet as the model - */ -public class SyncSetTreeContentProvider extends SyncSetContentProvider implements ITreeContentProvider { - - /* (non-Javadoc) - * @see org.eclipse.team.ccvs.syncviews.views.SyncSetContentProvider#getElements(java.lang.Object) - */ - public Object[] getElements(Object inputElement) { - return getChildren(inputElement); - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) - */ - public Object[] getChildren(Object element) { - IResource resource = getResource(element); - if (resource != null) { - return members(resource); - } else if (element instanceof SubscriberInput) { - return members(ResourcesPlugin.getWorkspace().getRoot()); - } - return new Object[0]; - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) - */ - public boolean hasChildren(Object element) { - return getChildren(element).length > 0; - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) - */ - public Object getParent(Object element) { - IResource resource = getResource(element); - if (resource == null) return null; - IContainer parent = resource.getParent(); - return getModelObject(parent); - } - - public AbstractTreeViewer getTreeViewer() { - if (viewer instanceof AbstractTreeViewer) { - return (AbstractTreeViewer)viewer; - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.team.ccvs.syncviews.views.SyncSetContentProvider#handleResourceAdditions(org.eclipse.team.ccvs.syncviews.views.SyncSetChangedEvent) - */ - protected void handleResourceAdditions(SyncSetChangedEvent event) { - AbstractTreeViewer tree = getTreeViewer(); - if (tree != null) { - IResource[] added = event.getAddedRoots(); - // TODO: Should group added roots by their parent - for (int i = 0; i < added.length; i++) { - IResource resource = added[i]; - Object parent; - if (resource.getType() == IResource.PROJECT) { - parent = getSubscriberInput(); - } else { - parent = getModelParent(resource); - } - Object element = getModelObject(resource); - tree.add(parent, element); - updateParentLabels(resource); - } - } else { - super.handleResourceAdditions(event); - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.ccvs.syncviews.views.SyncSetContentProvider#handleResourceRemovals(org.eclipse.team.ccvs.syncviews.views.SyncSetChangedEvent) - */ - protected void handleResourceRemovals(SyncSetChangedEvent event) { - AbstractTreeViewer tree = getTreeViewer(); - if (tree != null) { - IResource[] roots = event.getRemovedRoots(); - if (roots.length == 0) return; - Object[] modelRoots = new Object[roots.length]; - for (int i = 0; i < modelRoots.length; i++) { - modelRoots[i] = getModelObject(roots[i]); - updateParentLabels(roots[i]); - } - tree.remove(modelRoots); - } else { - super.handleResourceRemovals(event); - } - } - - protected Object getModelParent(IResource resource) { - return getModelObject(resource.getParent()); - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncTableViewer.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncTableViewer.java deleted file mode 100644 index 08baea02e..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncTableViewer.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.ui.synchronize.views; - -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Table; -import org.eclipse.team.internal.ui.synchronize.actions.INavigableControl; - -public class SyncTableViewer extends TableViewer implements INavigableControl { - - public SyncTableViewer(Table table) { - super(table); - } - - public boolean gotoDifference(int direction) { - Control c = getControl(); - - if (!(c instanceof Table)) - return false; - - Table table = (Table)c; - int inc = direction == NEXT ? 1 : -1; - int total = table.getItemCount(); - int next = table.getSelectionIndex() + inc; - if(next >= total || next < 0) { - return true; - } - table.setSelection(next); - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ui.sync.views.INavigableControl#preserveSelection(int) - */ - public void preserveState(int direction) { - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ui.sync.views.INavigableControl#restoreSelection(int) - */ - public void restoreState(int direction) { - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncTreeViewer.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncTreeViewer.java deleted file mode 100644 index 00d829e73..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncTreeViewer.java +++ /dev/null @@ -1,267 +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.ui.synchronize.views; - -import java.util.ArrayList; - -import org.eclipse.core.resources.IResource; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.jface.viewers.*; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.TreeItem; -import org.eclipse.team.internal.ui.IPreferenceIds; -import org.eclipse.team.internal.ui.TeamUIPlugin; -import org.eclipse.team.internal.ui.synchronize.actions.INavigableControl; - -/** - * Subclass of TreeViewer which handles decorator events properly. We should not need to create - * a subclass just for this! - */ -public class SyncTreeViewer extends TreeViewer implements INavigableControl { - - /** - * Change the tree layout between using compressed folders and regular folders - * when the user setting is changed. - */ - private IPropertyChangeListener propertyListener = new IPropertyChangeListener() { - public void propertyChange(PropertyChangeEvent event) { - if (event.getProperty().equals(IPreferenceIds.SYNCVIEW_COMPRESS_FOLDERS)) { - setTreeViewerContentProvider(); - } - } - }; - - public SyncTreeViewer(Composite parent, int style) { - super(parent, style); - getStore().addPropertyChangeListener(propertyListener); - setTreeViewerContentProvider(); - } - - private void setTreeViewerContentProvider() { - if (getStore().getBoolean(IPreferenceIds.SYNCVIEW_COMPRESS_FOLDERS)) { - setContentProvider(new CompressedFolderContentProvider()); - } else { - setContentProvider(new SyncSetTreeContentProvider()); - } - } - - /** - * Return the preference store for this plugin. - * @return IPreferenceStore for this plugin - */ - private IPreferenceStore getStore() { - return TeamUIPlugin.getPlugin().getPreferenceStore(); - } - - protected void handleLabelProviderChanged(LabelProviderChangedEvent event) { - Object[] changed= event.getElements(); - if (changed != null && getInput() != null) { - ArrayList others= new ArrayList(); - for (int i= 0; i < changed.length; i++) { - Object curr = changed[i]; - if (curr instanceof IResource) { - IContentProvider provider = getContentProvider(); - if (provider != null && provider instanceof SyncSetContentProvider) { - curr = ((SyncSetContentProvider)provider).getModelObject((IResource)curr); - } - } - others.add(curr); - } - if (others.isEmpty()) { - return; - } - event= new LabelProviderChangedEvent((IBaseLabelProvider) event.getSource(), others.toArray()); - } - super.handleLabelProviderChanged(event); - } - - /** - * Cleanup listeners and call super for content provider and label provider disposal. - */ - protected void handleDispose(DisposeEvent event) { - super.handleDispose(event); - getStore().removePropertyChangeListener(propertyListener); - } - - /** - * Selects the next (or previous) node of the current selection. - * If there is no current selection the first (last) node in the tree is selected. - * Wraps around at end or beginning. - * Clients may override. - * - * @param next if <code>true</code> the next node is selected, otherwise the previous node - */ - public boolean gotoDifference(int direction) { - boolean next = direction == INavigableControl.NEXT ? true : false; - return internalNavigate(next, false); - } - - /** - * Selects the next (or previous) node of the current selection. - * If there is no current selection the first (last) node in the tree is selected. - * Wraps around at end or beginning. - * Clients may override. - * - * @param next if <code>true</code> the next node is selected, otherwise the previous node - * @return <code>true</code> if at end (or beginning) - */ - private boolean internalNavigate(boolean next, boolean fireOpen) { - - Control c= getControl(); - if (!(c instanceof Tree)) - return false; - - Tree tree= (Tree) c; - TreeItem item= null; - TreeItem children[]= tree.getSelection(); - if (children != null && children.length > 0) - item= children[0]; - if (item == null) { - children= tree.getItems(); - if (children != null && children.length > 0) { - item= children[0]; - if (item != null && item.getItemCount() <= 0) { - internalSetSelection(item, fireOpen); // Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=20106 - return false; - } - } - } - - while (true) { - item= findNextPrev(item, next); - if (item == null) - break; - if (item.getItemCount() <= 0) - break; - } - - if (item != null) { - internalSetSelection(item, fireOpen); // Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=20106 - return false; - } - return true; - } - - private TreeItem findNextPrev(TreeItem item, boolean next) { - - if (item == null) - return null; - - TreeItem children[]= null; - - if (!next) { - - TreeItem parent= item.getParentItem(); - if (parent != null) - children= parent.getItems(); - else - children= item.getParent().getItems(); - - if (children != null && children.length > 0) { - // goto previous child - int index= 0; - for (; index < children.length; index++) - if (children[index] == item) - break; - - if (index > 0) { - - item= children[index-1]; - - while (true) { - createChildren(item); - int n= item.getItemCount(); - if (n <= 0) - break; - - item.setExpanded(true); - item= item.getItems()[n-1]; - } - - // previous - return item; - } - } - - // go up - return parent; - - } else { - item.setExpanded(true); - createChildren(item); - - if (item.getItemCount() > 0) { - // has children: go down - children= item.getItems(); - return children[0]; - } - - while (item != null) { - children= null; - TreeItem parent= item.getParentItem(); - if (parent != null) - children= parent.getItems(); - else - children= item.getParent().getItems(); - - if (children != null && children.length > 0) { - // goto next child - int index= 0; - for (; index < children.length; index++) - if (children[index] == item) - break; - - if (index < children.length-1) { - // next - return children[index+1]; - } - } - - // go up - item= parent; - } - } - - return item; - } - - private void internalSetSelection(TreeItem ti, boolean fireOpen) { - if (ti != null) { - Object data= ti.getData(); - if (data != null) { - // Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=20106 - ISelection selection= new StructuredSelection(data); - setSelection(selection, true); - ISelection currentSelection= getSelection(); - if (fireOpen && currentSelection != null && selection.equals(currentSelection)) { - fireOpen(new OpenEvent(this, selection)); - } - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ui.sync.views.INavigableControl#preserveState(int) - */ - public void preserveState(int direction) { - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ui.sync.views.INavigableControl#restoreState(int) - */ - public void restoreState(int direction) { - } -}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncViewerSorter.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncViewerSorter.java deleted file mode 100644 index 4a517183a..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncViewerSorter.java +++ /dev/null @@ -1,54 +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.ui.synchronize.views; - -import org.eclipse.core.resources.IResource; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.ui.views.navigator.ResourceSorter; - -/** - * This class sorts the model elements that appear in the SynchronizeView - */ -public class SyncViewerSorter extends ResourceSorter { - - private boolean compareFullPaths = false; - - /* (non-Javadoc) - * @see org.eclipse.ui.views.navigator.ResourceSorter#compareNames(org.eclipse.core.resources.IResource, org.eclipse.core.resources.IResource) - */ - protected int compareNames(IResource resource1, IResource resource2) { - if(compareFullPaths) { - return collator.compare(resource1.getFullPath().toString(), resource2.getFullPath().toString()); - } else { - return collator.compare(resource1.getName(), resource2.getName()); - } - } - - public SyncViewerSorter(int criteria) { - super(criteria); - } - - /* (non-Javadoc) - * Method declared on ViewerSorter. - */ - public int compare(Viewer viewer, Object o1, Object o2) { - if(o1 instanceof CompressedFolder || o2 instanceof CompressedFolder) { - compareFullPaths = true; - } - int result = super.compare(viewer, getResource(o1), getResource(o2)); - compareFullPaths = false; - return result; - } - - protected IResource getResource(Object obj) { - return SyncSetContentProvider.getResource(obj); - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncViewerTableSorter.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncViewerTableSorter.java deleted file mode 100644 index 291daa611..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SyncViewerTableSorter.java +++ /dev/null @@ -1,158 +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.ui.synchronize.views; - -import org.eclipse.core.resources.IResource; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.team.internal.ui.IPreferenceIds; -import org.eclipse.team.internal.ui.TeamUIPlugin; -import org.eclipse.ui.views.navigator.ResourceSorter; - -/** - * Provides support for sorting the table viewer of the SynchronizeView by column - */ -public class SyncViewerTableSorter extends SyncViewerSorter { - - private boolean reversed; - private int columnNumber; - - //column constants - public static final int COL_NAME = 0; - public static final int COL_PARENT = 1; - - // column headings: "Revision" "Tags" "Date" "Author" "Comment" - private int[][] SORT_ORDERS_BY_COLUMN = { - {COL_NAME, COL_PARENT}, /* name */ - {COL_PARENT, COL_NAME} /* parent */ - }; - - /** - * Return a listener that will change the sorter in the table when the column header - * is clicked. - */ - public static SelectionListener getColumnListener(final TableViewer tableViewer) { - /** - * This class handles selections of the column headers. - * Selection of the column header will cause resorting - * of the shown tasks using that column's sorter. - * Repeated selection of the header will toggle - * sorting order (ascending versus descending). - */ - return new SelectionAdapter() { - /** - * Handles the case of user selecting the - * header area. - * <p>If the column has not been selected previously, - * it will set the sorter of that column to be - * the current tasklist sorter. Repeated - * presses on the same column header will - * toggle sorting order (ascending/descending). - */ - public void widgetSelected(SelectionEvent e) { - // column selected - need to sort - int column = tableViewer.getTable().indexOf((TableColumn) e.widget); - SyncViewerTableSorter oldSorter = (SyncViewerTableSorter)tableViewer.getSorter(); - if (oldSorter != null && column == oldSorter.getColumnNumber()) { - SyncViewerTableSorter.getStore().setValue(IPreferenceIds.SYNCVIEW_VIEW_TABLESORT_REVERSED, !oldSorter.isReversed()); - oldSorter.setReversed(!oldSorter.isReversed()); - tableViewer.refresh(); - } else { - SyncViewerTableSorter.getStore().setValue(IPreferenceIds.SYNCVIEW_VIEW_TABLESORT, column); - SyncViewerTableSorter.getStore().setValue(IPreferenceIds.SYNCVIEW_VIEW_TABLESORT_REVERSED, false); - tableViewer.setSorter(new SyncViewerTableSorter()); - } - } - }; - } - - public SyncViewerTableSorter() { - super(ResourceSorter.NAME); - - this.columnNumber = getStore().getInt(IPreferenceIds.SYNCVIEW_VIEW_TABLESORT); - this.reversed = getStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_TABLESORT_REVERSED); - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.ViewerSorter#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) - */ - public int compare(Viewer viewer, Object e1, Object e2) { - - IResource resource1 = getResource(e1); - IResource resource2 = getResource(e2); - int result = 0; - if (resource1 == null || resource2 == null) { - result = super.compare(viewer, e1, e2); - } else { - int[] columnSortOrder = SORT_ORDERS_BY_COLUMN[columnNumber]; - for (int i = 0; i < columnSortOrder.length; ++i) { - result = compareColumnValue(columnSortOrder[i], resource1, resource2); - if (result != 0) - break; - } - } - if (reversed) - result = -result; - return result; - } - - /** - * Compares two resources, based only on the value of the specified column. - */ - int compareColumnValue(int columnNumber, IResource e1, IResource e2) { - switch (columnNumber) { - case COL_NAME: /* revision */ - - // Category behavior from superclass - int cat1 = category(e1); - int cat2 = category(e2); - - if (cat1 != cat2) - return cat1 - cat2; - - // cat1 == cat2 - - return getCollator().compare(e1.getName(), e2.getName()); - case COL_PARENT: /* parent */ - return getCollator().compare(e1.getParent().getFullPath().toString(), e2.getParent().getFullPath().toString()); - default: - return 0; - } - } - /** - * Returns the number of the column by which this is sorting. - */ - public int getColumnNumber() { - return columnNumber; - } - /** - * Returns true for descending, or false - * for ascending sorting order. - */ - public boolean isReversed() { - return reversed; - } - /** - * Sets the sorting order. - */ - public void setReversed(boolean newReversed) { - reversed = newReversed; - } - - private static IPreferenceStore getStore() { - return TeamUIPlugin.getPlugin().getPreferenceStore(); - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SynchronizeViewNode.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SynchronizeViewNode.java deleted file mode 100644 index 50e10ed5d..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/views/SynchronizeViewNode.java +++ /dev/null @@ -1,116 +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.ui.synchronize.views; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.core.subscribers.TeamSubscriber; -import org.eclipse.team.internal.ui.synchronize.sets.SubscriberInput; -import org.eclipse.team.internal.ui.synchronize.sets.SyncSet; -import org.eclipse.team.ui.synchronize.ITeamSubscriberParticipantNode; - -/** - * A SynchronizeViewNode instance appears in the Synchronize View. Actions contributed to - * the view can use these instances to determine the set of resources - * shown based on the current filter applied to the view. - * <p> - * @see org.eclipse.team.ui.sync.ISynchronizeViewNode - */ -public class SynchronizeViewNode implements IAdaptable, ITeamSubscriberParticipantNode { - - private IResource resource; - private SubscriberInput input; - - /** - * Construct a SynchromizeViewNode - * @param input The SubscriberInput for the node. - * @param resource The resource for the node - */ - public SynchronizeViewNode(SubscriberInput input, IResource resource) { - this.input = input; - this.resource = resource; - } - - protected SyncSet getSyncSet() { - return input.getFilteredSyncSet(); - } - - public SubscriberInput getSubscriberInput() { - return input; - } - - /* (non-Javadoc) - * @see org.eclipse.team.ui.sync.ISynchronizeViewNode#getTeamSubscriber() - */ - public TeamSubscriber getTeamSubscriber() { - return input.getSubscriber(); - } - - /* (non-Javadoc) - * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) - */ - public Object getAdapter(Class adapter) { - if (adapter == SyncInfo.class) { - return getSyncInfo(); - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.team.ui.sync.ISynchronizeViewNode#getSyncInfo() - */ - public SyncInfo getSyncInfo() { - return getSyncSet().getSyncInfo(resource); - } - - /* (non-Javadoc) - * @see org.eclipse.team.ui.sync.ISynchronizeViewNode#getChildSyncInfos() - */ - public SyncInfo[] getChildSyncInfos() { - return getSyncSet().getOutOfSyncDescendants(resource); - } - - /** - * Return true if the receiver's TeamSubscriber and Resource are equal to that of object. - * @param object The object to test - * @return true has the same subsriber and resource - */ - public boolean equals(Object object) { - if (object instanceof SynchronizeViewNode) { - SynchronizeViewNode syncViewNode = (SynchronizeViewNode) object; - return getTeamSubscriber().equals(syncViewNode.getTeamSubscriber()) && - getResource().equals(syncViewNode.getResource()); - } - return super.equals(object); - } - - /* (non-Javadoc) - * @see java.lang.Object#hashCode() - */ - public int hashCode() { - return getResource().hashCode() | getTeamSubscriber().hashCode(); - } - - /** - * @return IResource The receiver's resource - */ - public IResource getResource() { - return resource; - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - public String toString() { - return "SynchronizeViewNode for " + getResource().getFullPath().toString(); //$NON-NLS-1$ - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ISharedImages.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ISharedImages.java index 440c7c0db..b827bebb5 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ISharedImages.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ISharedImages.java @@ -73,9 +73,9 @@ public interface ISharedImages { //objects public final String IMG_SITE_ELEMENT = "clcl16/site_element.gif"; //$NON-NLS-1$ - public final String IMG_CHANGE_FILTER = "clcl16/change_filter.gif"; //$NON-NLS-1$ - - // TODO: I just picked an image. We should get a custom image + public final String IMG_CHANGE_FILTER = "clcl16/change_filter.gif"; //$NON-NLS-1$ public final String IMG_COMPRESSED_FOLDER = "obj/compressed_folder_obj.gif"; //$NON-NLS-1$ + public final String IMG_WARNING = "ovr/warning_co.gif"; //$NON-NLS-1$ + } diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ITeamUIConstants.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ITeamUIConstants.java index a582618b5..0aa50c41b 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ITeamUIConstants.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ITeamUIConstants.java @@ -16,4 +16,5 @@ public interface ITeamUIConstants { public static final String PT_SYNCPARTICIPANTS = "synchronizeParticipants"; //$NON-NLS-1$ public static final String PT_CONFIGURATION ="configurationWizards"; //$NON-NLS-1$ public static final String PT_TARGETCONFIG ="targetConfigWizards"; //$NON-NLS-1$ + public static final String PT_LOGICAL_VIEWS = "logicalViews"; //$NON-NLS-1$ } diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/AbstractSynchronizeParticipant.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/AbstractSynchronizeParticipant.java index e384ec2ca..7da095d8d 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/AbstractSynchronizeParticipant.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/AbstractSynchronizeParticipant.java @@ -110,7 +110,14 @@ public abstract class AbstractSynchronizeParticipant implements ISynchronizePart public String getId() { return fId; } - + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.ISynchronizeParticipant#isPersistent() + */ + public boolean isPersistent() { + return true; + } + /* * (non-Javadoc) * diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ISynchronizeParticipant.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ISynchronizeParticipant.java index 1b74fe2bf..4daa0e83f 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ISynchronizeParticipant.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ISynchronizeParticipant.java @@ -18,12 +18,30 @@ import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.IPageBookViewPage; /** - * A synchronize participant provides a logical connection between local - * resources and a remote location that is used to share those resources. The - * Synchronize View displays synchronize participants. + * A synchronize participant is shown in the <code>Synchronize View</code>. Typically + * a participant will show changes between local resources and variant states of + * those resources. For example, a participant could show the relative synchronization + * between local resources and those on an FTP server, or alternatively, between local + * resources and local history. * <p> - * A participant must create a page that will be displayed in the - * ISynchronizeView page book view. Clients may implement this interface. + * A participant is added to the Synchronize View in three steps: + * <ol> + * <li>A <code>synchronizeParticipant</code> extension is contributed to + * the team registry. This extension defines the participant id, + * name, icon, type, and participant class.</li> + * <li>The participant is included in the Synchronize View when the view is + * created if its type is <code>static</code>.</li> + * <li>If a participant is not static, plug-in developers can add the + * participant to the view by adding the participant via + * {@link ISynchronizeManager#addSynchronizeParticipants(ISynchronizeParticipant[]) and + * remove it using {@link ISynchronizeManager#removeSynchronizeParticipants(ISynchronizeParticipant[]). + * </ol> + * </p> + * <p> + * A participant must create a page that will be displayed in the ISynchronizeView page + * book view. + * </p><p> + * Clients may implement this interface. * </p> * @see ISynchronizeView * @see ISynchronizeManager @@ -48,6 +66,15 @@ public interface ISynchronizeParticipant extends IExecutableExtension { public String getName(); /** + * Returns <code>true</code> if this participant should be persisted between + * workbench sessions and <code>false</code> otherwise. + * + * @return <code>true</code> if this participant should be persisted between + * workbench sessions and <code>false</code> otherwise. + */ + public boolean isPersistent(); + + /** * Returns an image descriptor for this synchronize participant, or <code>null</code> * if none. * @@ -66,7 +93,7 @@ public interface ISynchronizeParticipant extends IExecutableExtension { * participant */ public IPageBookViewPage createPage(ISynchronizeView view); - + /** * Initializes this participant with the given participant state. * A memento is passed to the participant which contains a snapshot diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ISynchronizeParticipantDescriptor.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ISynchronizeParticipantDescriptor.java index 1eed9ba6d..9a0a99fac 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ISynchronizeParticipantDescriptor.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ISynchronizeParticipantDescriptor.java @@ -18,7 +18,7 @@ import org.eclipse.jface.resource.ImageDescriptor; * for a registered participant type in the declaring plug-in's * manifest (<code>plugin.xml</code>) file. * <p> - * This interface is not intended to be implemented by clients. + * Clients are not intended to implement this interface. * </p> * @see ISynchronizeManager#getParticipantDescriptor(String) * @since 3.0 diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ISynchronizeView.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ISynchronizeView.java index fc080bcdf..0fdf85d87 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ISynchronizeView.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ISynchronizeView.java @@ -20,7 +20,8 @@ import org.eclipse.ui.IViewPart; * between participants. * <p> * Clients should not add viewActions to this view because they will be global - * to all participants. Instead, add participant specific actions. + * to all participants. Instead, add participant specific actions as described + * in {@link TreeViewerAdvisor}. * </p> * <p> * Clients are not intended to implement this interface. diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ITeamSubscriberParticipantNode.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ITeamSubscriberParticipantNode.java deleted file mode 100644 index 155fb0661..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ITeamSubscriberParticipantNode.java +++ /dev/null @@ -1,53 +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.ui.synchronize; - -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.core.subscribers.TeamSubscriber; - -/** - * ITeamSubscriberParticipantNode is used in the page created by the - * <code>TeamSubscriberParticipant<code> to display the kind of change - * detected in a two or three-way synchronize operation. They are the - * nodes shown in the Synchronize View. - * <p> - * Actions contributed to the TeamSubscriberParticipant will operate - * on these nodes. A common super class {@link SubscriberAction} exists - * to help create actions that are contributed to the TeamSubscriberParticipant. - * It contains helpers for accessing and filtering these nodes. - * </p> - * @see TeamSubscriberParticipantPage - * @see SubscriberAction - * @since 3.0 - */ -public interface ITeamSubscriberParticipantNode { - /** - * Answer the receiver's Subscriber - * - * @return the node's TeamSubscriber - */ - public abstract TeamSubscriber getTeamSubscriber(); - /** - * Returns the SyncInfo for this node. Note that the SynchronizeView only - * creates nodes for resources that are out-of-sync. - * - * @return SyncInfo the sync info for this node - */ - public abstract SyncInfo getSyncInfo(); - /** - * Return an array that contains all children (including the receiver) that - * have SyncInfos that are out-of-sync. Returns an empty array if this node - * does not have children. - * - * @return SyncInfo[] all out-of-sync child resources. - */ - public abstract SyncInfo[] getChildSyncInfos(); -}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/TeamSubscriberParticipant.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/TeamSubscriberParticipant.java deleted file mode 100644 index 957b6fb11..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/TeamSubscriberParticipant.java +++ /dev/null @@ -1,200 +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.ui.synchronize; - -import org.eclipse.core.resources.IResource; -import org.eclipse.team.core.subscribers.TeamSubscriber; -import org.eclipse.team.internal.ui.IPreferenceIds; -import org.eclipse.team.internal.ui.TeamUIPlugin; -import org.eclipse.team.internal.ui.jobs.RefreshSubscriberInputJob; -import org.eclipse.team.internal.ui.synchronize.actions.RefreshAction; -import org.eclipse.team.internal.ui.synchronize.sets.SubscriberInput; -import org.eclipse.ui.*; -import org.eclipse.ui.part.IPageBookViewPage; - -/** - * A synchronize participant that displays synchronization information for local - * resources that are managed via a {@link TeamSubscriber}. - * - * @since 3.0 - */ -public abstract class TeamSubscriberParticipant extends AbstractSynchronizeParticipant { - - private SubscriberInput input; - private int currentMode; - private int currentLayout; - private IWorkingSet workingSet; - - /** - * Key for settings in memento - */ - private static final String CTX_SUBSCRIBER_PARTICIPANT_SETTINGS = TeamUIPlugin.ID + ".TEAMSUBSRCIBERSETTINGS"; //$NON-NLS-1$ - - /** - * Property constant indicating the mode of a page has changed. - */ - public static final String P_SYNCVIEWPAGE_WORKINGSET = TeamUIPlugin.ID + ".P_SYNCVIEWPAGE_WORKINGSET"; //$NON-NLS-1$ - - /** - * Property constant indicating the mode of a page has changed. - */ - public static final String P_SYNCVIEWPAGE_MODE = TeamUIPlugin.ID + ".P_SYNCVIEWPAGE_MODE"; //$NON-NLS-1$ - - /** - * Modes are direction filters for the view - */ - public final static int INCOMING_MODE = 0x1; - public final static int OUTGOING_MODE = 0x2; - public final static int BOTH_MODE = 0x4; - public final static int CONFLICTING_MODE = 0x8; - public final static int ALL_MODES = INCOMING_MODE | OUTGOING_MODE | CONFLICTING_MODE | BOTH_MODE; - - /** - * Property constant indicating the mode of a page has changed. - */ - public static final String P_SYNCVIEWPAGE_LAYOUT = TeamUIPlugin.ID + ".P_SYNCVIEWPAGE_LAYOUT"; //$NON-NLS-1$ - - /** - * View type constant (value 0) indicating that the synchronize view will be shown - * as a tree. - */ - public static final int TREE_LAYOUT = 0; - - /** - * View type constant (value 1) indicating that the synchronize view will be shown - * as a table. - */ - public static final int TABLE_LAYOUT = 1; - - public TeamSubscriberParticipant() { - super(); - } - - /* (non-Javadoc) - * @see org.eclipse.team.ui.sync.ISynchronizeViewPage#createPage(org.eclipse.team.ui.sync.ISynchronizeView) - */ - public IPageBookViewPage createPage(ISynchronizeView view) { - return new TeamSubscriberParticipantPage(this, view, input); - } - - public void setMode(int mode) { - int oldMode = getMode(); - currentMode = mode; - TeamUIPlugin.getPlugin().getPreferenceStore().setValue(IPreferenceIds.SYNCVIEW_SELECTED_MODE, mode); - firePropertyChange(this, P_SYNCVIEWPAGE_MODE, new Integer(oldMode), new Integer(mode)); - } - - public int getMode() { - return currentMode; - } - - public void setLayout(int layout) { - int oldLayout = currentLayout; - currentLayout = layout; - firePropertyChange(this, P_SYNCVIEWPAGE_LAYOUT, new Integer(oldLayout), new Integer(layout)); - } - - public int getLayout() { - return currentLayout; - } - - public void setWorkingSet(IWorkingSet set) { - SubscriberInput input = getInput(); - IWorkingSet oldSet = null; - if(input != null) { - oldSet = input.getWorkingSet(); - input.setWorkingSet(set); - workingSet = null; - } else { - workingSet = set; - } - firePropertyChange(this, P_SYNCVIEWPAGE_WORKINGSET, oldSet, set); - } - - public IWorkingSet getWorkingSet() { - SubscriberInput input = getInput(); - if(input != null) { - return getInput().getWorkingSet(); - } else { - return workingSet; - } - } - - public void refreshWithRemote(IResource[] resources) { - if((resources == null || resources.length == 0)) { - RefreshAction.run(input.workingSetRoots(), this); - } else { - RefreshAction.run(resources, this); - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.ui.sync.AbstractSynchronizeViewPage#dispose() - */ - public void dispose() { - RefreshSubscriberInputJob refreshJob = TeamUIPlugin.getPlugin().getRefreshJob(); - refreshJob.removeSubscriberInput(input); - input.dispose(); - } - - /* - * For testing only! - */ - public SubscriberInput getInput() { - return input; - } - - protected void setSubscriber(TeamSubscriber subscriber) { - this.input = new SubscriberInput(this, subscriber); - if(workingSet != null) { - setWorkingSet(workingSet); - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.ui.synchronize.ISynchronizeParticipant#init(org.eclipse.ui.IMemento) - */ - public void init(IMemento memento) throws PartInitException { - if(memento != null) { - IMemento settings = memento.getChild(CTX_SUBSCRIBER_PARTICIPANT_SETTINGS); - if(settings != null) { - String set = settings.getString(P_SYNCVIEWPAGE_WORKINGSET); - String mode = settings.getString(P_SYNCVIEWPAGE_MODE); - String layout = settings.getString(P_SYNCVIEWPAGE_LAYOUT); - - if(set != null) { - IWorkingSet workingSet = PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSet(set); - if(workingSet != null) { - setWorkingSet(workingSet); - } - } - setMode(Integer.parseInt(mode)); - setLayout(Integer.parseInt(layout)); - } - } else { - setMode(BOTH_MODE); - setLayout(TREE_LAYOUT); - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.ui.synchronize.ISynchronizeParticipant#saveState(org.eclipse.ui.IMemento) - */ - public void saveState(IMemento memento) { - IMemento settings = memento.createChild(CTX_SUBSCRIBER_PARTICIPANT_SETTINGS); - IWorkingSet set = getWorkingSet(); - if(set != null) { - settings.putString(P_SYNCVIEWPAGE_WORKINGSET, getWorkingSet().getName()); - } - settings.putString(P_SYNCVIEWPAGE_LAYOUT, Integer.toString(getLayout())); - settings.putString(P_SYNCVIEWPAGE_MODE, Integer.toString(getMode())); - } -}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/TeamSubscriberParticipantLabelProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/TeamSubscriberParticipantLabelProvider.java deleted file mode 100644 index bb96a3122..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/TeamSubscriberParticipantLabelProvider.java +++ /dev/null @@ -1,255 +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.ui.synchronize; - -import java.util.*; - -import org.eclipse.compare.CompareConfiguration; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.QualifiedName; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.*; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.*; -import org.eclipse.swt.widgets.Display; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.core.sync.IRemoteSyncElement; -import org.eclipse.team.internal.ui.*; -import org.eclipse.team.internal.ui.jobs.IJobListener; -import org.eclipse.team.internal.ui.jobs.JobStatusHandler; -import org.eclipse.team.internal.ui.synchronize.sets.*; -import org.eclipse.team.internal.ui.synchronize.views.*; -import org.eclipse.team.ui.ISharedImages; -import org.eclipse.team.ui.synchronize.actions.SubscriberAction; -import org.eclipse.ui.internal.WorkbenchColors; -import org.eclipse.ui.model.WorkbenchLabelProvider; - -/** - * Provides basic labels for the subscriber participant synchronize view - * page. This class provides a facility for subclasses to define annotations - * on the labels and icons of adaptable objects by overriding - * <code>decorateText()</code> and <code>decorateImage</code>. - * - * @see TeamSubscriberParticipantPage#getLabelProvider() - * @since 3.0 - */ -public class TeamSubscriberParticipantLabelProvider extends LabelProvider implements ITableLabelProvider, IColorProvider { - - //column constants - private static final int COL_RESOURCE = 0; - private static final int COL_PARENT = 1; - private boolean working = false; - - private Image compressedFolderImage; - - // cache for folder images that have been overlayed with conflict icon - private Map fgImageCache; - - // Keep track of the compare and workbench image providers - // so they can be properly disposed - CompareConfiguration compareConfig = new CompareConfiguration(); - WorkbenchLabelProvider workbenchLabelProvider = new WorkbenchLabelProvider(); - - public Image getCompressedFolderImage() { - if (compressedFolderImage == null) { - compressedFolderImage = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_COMPRESSED_FOLDER).createImage(); - } - return compressedFolderImage; - } - - public TeamSubscriberParticipantLabelProvider() { - JobStatusHandler.addJobListener(new IJobListener() { - public void started(QualifiedName jobType) { - working = true; - Display.getDefault().asyncExec(new Runnable() { - public void run() { - synchronized (this) { - fireLabelProviderChanged(new LabelProviderChangedEvent(TeamSubscriberParticipantLabelProvider.this)); - } - } - }); - } - public void finished(QualifiedName jobType) { - working = false; - Display.getDefault().asyncExec(new Runnable() { - public void run() { - synchronized (this) { - fireLabelProviderChanged(new LabelProviderChangedEvent(TeamSubscriberParticipantLabelProvider.this)); - } - } - }); - - } - }, SubscriberAction.SUBSCRIBER_JOB_TYPE); - - // The label provider may of been created after the subscriber job has been - // started. - this.working = JobStatusHandler.hasRunningJobs(SubscriberAction.SUBSCRIBER_JOB_TYPE); - - - } - - protected String decorateText(String input, Object resource) { - return input; - } - - protected Image decorateImage(Image base, Object resource) { - return base; - } - - public String getText(Object element) { - String name; - IResource resource = SyncSetContentProvider.getResource(element); - if (element instanceof CompressedFolder) { - name = resource.getProjectRelativePath().toString(); - } else { - name = workbenchLabelProvider.getText(resource); - } - if (TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_SYNCINFO_IN_LABEL)) { - SyncInfo info = SyncSetContentProvider.getSyncInfo(element); - if (info != null && info.getKind() != SyncInfo.IN_SYNC) { - String syncKindString = SyncInfo.kindToString(info.getKind()); - name = Policy.bind("TeamSubscriberSyncPage.labelWithSyncKind", name, syncKindString); //$NON-NLS-1$ - } - } - return decorateText(name, resource); - } - - /** - * An image is decorated by at most 3 different plugins. - * 1. ask the workbench for the default icon for the resource - * 2. ask the compare plugin for the sync kind overlay - * 3. overlay the conflicting image on folders/projects containing conflicts - */ - public Image getImage(Object element) { - Image decoratedImage = null; - IResource resource = SyncSetContentProvider.getResource(element); - if (element instanceof CompressedFolder) { - decoratedImage = compareConfig.getImage(getCompressedFolderImage(), IRemoteSyncElement.IN_SYNC); - } else { - Image image = workbenchLabelProvider.getImage(resource); - decoratedImage = getCompareImage(image, element); - } - decoratedImage = propagateConflicts(decoratedImage, element, resource); - return decorateImage(decoratedImage, element); - } - - private Image getCompareImage(Image base, Object element) { - int kind = SyncSetContentProvider.getSyncKind(element); - switch (kind & SyncInfo.DIRECTION_MASK) { - case SyncInfo.OUTGOING: - kind = (kind &~ SyncInfo.OUTGOING) | SyncInfo.INCOMING; - break; - case IRemoteSyncElement.INCOMING: - kind = (kind &~ SyncInfo.INCOMING) | SyncInfo.OUTGOING; - break; - } - return compareConfig.getImage(base, kind); - } - - private Image propagateConflicts(Image base, Object element, IResource resource) { - if(element instanceof SynchronizeViewNode && resource.getType() != IResource.FILE) { - // if the folder is already conflicting then don't bother propagating the conflict - int kind = SyncSetContentProvider.getSyncKind(element); - if((kind & SyncInfo.DIRECTION_MASK) != SyncInfo.CONFLICTING) { - SubscriberInput input = ((SynchronizeViewNode)element).getSubscriberInput(); - SyncSet set = new SyncSet(); - SyncInfo[] infos = input.getWorkingSetSyncSet().getOutOfSyncDescendants(resource); - for (int i = 0; i < infos.length; i++) { - set.add(infos[i]); - } - SyncInfoStatistics stats = set.getStatistics(); - long count = stats.countFor(SyncInfo.CONFLICTING, SyncInfo.DIRECTION_MASK); - if(count > 0) { - ImageDescriptor overlay = new OverlayIcon( - base, - new ImageDescriptor[] { TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_CONFLICT_OVR)}, - new int[] {OverlayIcon.BOTTOM_LEFT}, - new Point(base.getBounds().width, base.getBounds().height)); - - if(fgImageCache == null) { - fgImageCache = new HashMap(10); - } - Image conflictDecoratedImage = (Image) fgImageCache.get(overlay); - if (conflictDecoratedImage == null) { - conflictDecoratedImage = overlay.createImage(); - fgImageCache.put(overlay, conflictDecoratedImage); - } - return conflictDecoratedImage; - } - } - } - return base; - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose() - */ - public void dispose() { - super.dispose(); - workbenchLabelProvider.dispose(); - compareConfig.dispose(); - if (compressedFolderImage != null) { - compressedFolderImage.dispose(); - } - if(fgImageCache != null) { - Iterator it = fgImageCache.values().iterator(); - while (it.hasNext()) { - Image element = (Image) it.next(); - element.dispose(); - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int) - */ - public Image getColumnImage(Object element, int columnIndex) { - if (columnIndex == COL_RESOURCE) { - return getImage(element); - } else if (columnIndex == COL_PARENT) { - IResource resource = SyncSetContentProvider.getResource(element); - return null; - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int) - */ - public String getColumnText(Object element, int columnIndex) { - if (columnIndex == COL_RESOURCE) { - return getText(element); - } else if (columnIndex == COL_PARENT) { - IResource resource = SyncSetContentProvider.getResource(element); - return resource.getParent().getFullPath().toString(); - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.IColorProvider#getForeground(java.lang.Object) - */ - public Color getForeground(Object element) { - if (working) { - return WorkbenchColors.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); - } else { - return null; - } - } - - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.IColorProvider#getBackground(java.lang.Object) - */ - public Color getBackground(Object element) { - return null; - } -}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/TeamSubscriberParticipantPage.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/TeamSubscriberParticipantPage.java deleted file mode 100644 index 21f0ec6ad..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/TeamSubscriberParticipantPage.java +++ /dev/null @@ -1,598 +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.ui.synchronize; - -import java.util.Iterator; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jface.action.*; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; -import org.eclipse.jface.viewers.*; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.*; -import org.eclipse.swt.events.MenuListener; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.*; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.internal.ui.*; -import org.eclipse.team.internal.ui.jobs.JobBusyCursor; -import org.eclipse.team.internal.ui.synchronize.actions.*; -import org.eclipse.team.internal.ui.synchronize.sets.SubscriberInput; -import org.eclipse.team.internal.ui.synchronize.views.*; -import org.eclipse.team.ui.synchronize.actions.SubscriberAction; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter; -import org.eclipse.ui.*; -import org.eclipse.ui.internal.PluginAction; -import org.eclipse.ui.part.*; -import org.eclipse.ui.views.navigator.ResourceSorter; - -/** - * A synchronize view page that works with participants that are subclasses of - * {@link TeamSubscriberParticipant}. It shows changes in the tree or table view - * and supports navigation, opening, and filtering changes. - * <p> - * Clients can subclass to extend the label decoration or add action bar - * contributions. For more extensive modifications, clients should create - * their own custom control. - * </p> - * @since 3.0 - */ -public class TeamSubscriberParticipantPage implements IPageBookViewPage, IPropertyChangeListener { - // The viewer that is shown in the view. Currently this can be either a table or tree viewer. - private StructuredViewer viewer; - - // Parent composite of this view. It is remembered so that we can dispose of its children when - // the viewer type is switched. - private Composite composite = null; - private boolean settingWorkingSet = false; - - // Viewer type constants - private int layout; - - // Remembering the current input and the previous. - private SubscriberInput input = null; - - // A set of common actions. They are hooked to the active SubscriberInput and must - // be reset when the input changes. - // private SyncViewerActions actions; - - private JobBusyCursor busyCursor; - private ISynchronizeView view; - private TeamSubscriberParticipant participant; - private IPageSite site; - - public final static int[] INCOMING_MODE_FILTER = new int[] {SyncInfo.CONFLICTING, SyncInfo.INCOMING}; - public final static int[] OUTGOING_MODE_FILTER = new int[] {SyncInfo.CONFLICTING, SyncInfo.OUTGOING}; - public final static int[] BOTH_MODE_FILTER = new int[] {SyncInfo.CONFLICTING, SyncInfo.INCOMING, SyncInfo.OUTGOING}; - public final static int[] CONFLICTING_MODE_FILTER = new int[] {SyncInfo.CONFLICTING}; - - // Actions - private OpenWithActionGroup openWithActions; - private NavigateAction gotoNext; - private NavigateAction gotoPrevious; - private Action toggleLayoutTree; - private Action toggleLayoutTable; - private RefactorActionGroup refactorActions; - private SyncViewerShowPreferencesAction showPreferences; - private RefreshAction refreshAllAction; - private RefreshAction refreshSelectionAction; - private ComparisonCriteriaActionGroup comparisonCriteriaGroup; - private Action collapseAll; - private Action expandAll; - private WorkingSetFilterActionGroup workingSetGroup; - private StatusLineContributionGroup statusLine; - - /** - * Constructs a new SynchronizeView. - */ - public TeamSubscriberParticipantPage(TeamSubscriberParticipant page, ISynchronizeView view, SubscriberInput input) { - this.participant = page; - this.view = view; - this.input = input; - layout = getStore().getInt(IPreferenceIds.SYNCVIEW_VIEW_TYPE); - if (layout != TeamSubscriberParticipant.TREE_LAYOUT) { - layout = TeamSubscriberParticipant.TABLE_LAYOUT; - } - } - - /* (non-Javadoc) - * @see org.eclipse.ui.part.IPage#createControl(org.eclipse.swt.widgets.Composite) - */ - public void createControl(Composite parent) { - composite = new Composite(parent, SWT.NONE); - GridLayout gridLayout= new GridLayout(); - gridLayout.makeColumnsEqualWidth= false; - gridLayout.marginWidth= 0; - gridLayout.marginHeight = 0; - gridLayout.verticalSpacing = 0; - composite.setLayout(gridLayout); - - // Create the busy cursor with no control to start with (createViewer will set it) - busyCursor = new JobBusyCursor(parent.getParent().getParent(), SubscriberAction.SUBSCRIBER_JOB_TYPE); - createViewer(composite); - - // create actions - openWithActions = new OpenWithActionGroup(this); - refactorActions = new RefactorActionGroup(view); - gotoNext = new NavigateAction(view, this, INavigableControl.NEXT); - gotoPrevious = new NavigateAction(view, this, INavigableControl.PREVIOUS); - comparisonCriteriaGroup = new ComparisonCriteriaActionGroup(input); - - toggleLayoutTable = new ToggleViewLayoutAction(participant, TeamSubscriberParticipant.TABLE_LAYOUT); - toggleLayoutTree = new ToggleViewLayoutAction(participant, TeamSubscriberParticipant.TREE_LAYOUT); - workingSetGroup = new WorkingSetFilterActionGroup(getSite().getShell(), this, view, participant); - - showPreferences = new SyncViewerShowPreferencesAction(view.getSite().getShell()); - - refreshAllAction = new RefreshAction(getSite().getPage(), getParticipant(), true /* refresh all */); - refreshSelectionAction = new RefreshAction(getSite().getPage(), getParticipant(), false /* refresh all */); - statusLine = new StatusLineContributionGroup(getSite().getShell(), workingSetGroup, getParticipant()); - - collapseAll = new Action() { - public void run() { - collapseAll(); - } - }; - Utils.initAction(collapseAll, "action.collapseAll."); //$NON-NLS-1$ - - expandAll = new Action() { - public void run() { - Viewer viewer = getViewer(); - ISelection selection = viewer.getSelection(); - if(viewer instanceof AbstractTreeViewer && ! selection.isEmpty()) { - Iterator elements = ((IStructuredSelection)selection).iterator(); - while (elements.hasNext()) { - Object next = elements.next(); - ((AbstractTreeViewer) viewer).expandToLevel(next, AbstractTreeViewer.ALL_LEVELS); - } - } - } - }; - Utils.initAction(expandAll, "action.expandAll."); //$NON-NLS-1$ - - participant.addPropertyChangeListener(this); - TeamUIPlugin.getPlugin().getPreferenceStore().addPropertyChangeListener(this); - updateMode(participant.getMode()); - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite, org.eclipse.ui.IMemento) - */ - public void init(IPageSite site) throws PartInitException { - this.site = site; - } - - private void hookContextMenu() { - if(getViewer() != null) { - final MenuManager menuMgr = new MenuManager(participant.getId()); //$NON-NLS-1$ - menuMgr.setRemoveAllWhenShown(true); - menuMgr.addMenuListener(new IMenuListener() { - public void menuAboutToShow(IMenuManager manager) { - setContextMenu(manager); - } - }); - Menu menu = menuMgr.createContextMenu(viewer.getControl()); - menu.addMenuListener(new MenuListener() { - public void menuHidden(MenuEvent e) { - } - // Hack to allow action contributions to update their - // state before the menu is shown. This is required when - // the state of the selection changes and the contributions - // need to update enablement based on this. - public void menuShown(MenuEvent e) { - IContributionItem[] items = menuMgr.getItems(); - for (int i = 0; i < items.length; i++) { - IContributionItem item = items[i]; - if(item instanceof ActionContributionItem) { - IAction actionItem = ((ActionContributionItem)item).getAction(); - if(actionItem instanceof PluginAction) { - ((PluginAction)actionItem).selectionChanged(TeamSubscriberParticipantPage.this.viewer.getSelection()); - } - } - } - } - }); - viewer.getControl().setMenu(menu); - getSite().registerContextMenu(participant.getId(), menuMgr, viewer); - } - } - - private void setContextMenu(IMenuManager manager) { - openWithActions.fillContextMenu(manager); - refactorActions.fillContextMenu(manager); - manager.add(refreshSelectionAction); - manager.add(new Separator()); - manager.add(expandAll); - manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); - } - - /** - * Toggles between label/tree/table viewers. - */ - public void switchViewerType(int viewerType) { - if(viewer == null || viewerType != layout) { - if (composite == null || composite.isDisposed()) return; - IStructuredSelection oldSelection = null; - if(viewer != null) { - oldSelection = (IStructuredSelection)viewer.getSelection(); - } - layout = viewerType; - getStore().setValue(IPreferenceIds.SYNCVIEW_VIEW_TYPE, layout); - disposeChildren(composite); - createViewer(composite); - composite.layout(); - if(oldSelection == null || oldSelection.size() == 0) { - //gotoDifference(INavigableControl.NEXT); - } else { - viewer.setSelection(oldSelection, true); - } - } - } - - /** - * Adds the listeners to the viewer. - */ - private void initializeListeners() { - viewer.addSelectionChangedListener(new ISelectionChangedListener() { - public void selectionChanged(SelectionChangedEvent event) { - updateStatusLine((IStructuredSelection)event.getSelection()); - } - }); - viewer.addDoubleClickListener(new IDoubleClickListener() { - public void doubleClick(DoubleClickEvent event) { - handleDoubleClick(event); - } - }); - viewer.addOpenListener(new IOpenListener() { - public void open(OpenEvent event) { - handleOpen(event); - } - }); - } - - private void createViewer(Composite parent) { - //tbMgr.createControl(parent); - switch(layout) { - case TeamSubscriberParticipant.TREE_LAYOUT: - createTreeViewerPartControl(parent); - break; - case TeamSubscriberParticipant.TABLE_LAYOUT: - createTableViewerPartControl(parent); - break; - } - viewer.setInput(input); - viewer.getControl().setFocus(); - initializeListeners(); - hookContextMenu(); - getSite().setSelectionProvider(getViewer()); - } - - protected ILabelProvider getLabelProvider() { - return new TeamSubscriberParticipantLabelProvider(); - } - - private void createTreeViewerPartControl(Composite parent) { - GridData data = new GridData(GridData.FILL_BOTH); - viewer = new SyncTreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); - viewer.setLabelProvider(getLabelProvider()); - viewer.setSorter(new SyncViewerSorter(ResourceSorter.NAME)); - ((TreeViewer)viewer).getTree().setLayoutData(data); - } - - private void createTableViewerPartControl(Composite parent) { - // Create the table - Table table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION); - table.setHeaderVisible(true); - table.setLinesVisible(true); - GridData data = new GridData(GridData.FILL_BOTH); - table.setLayoutData(data); - - // Set the table layout - TableLayout layout = new TableLayout(); - table.setLayout(layout); - - // Create the viewer - TableViewer tableViewer = new SyncTableViewer(table); - - // Create the table columns - createColumns(table, layout, tableViewer); - - // Set the table contents - viewer = tableViewer; - viewer.setContentProvider(new SyncSetTableContentProvider()); - viewer.setLabelProvider(getLabelProvider()); - viewer.setSorter(new SyncViewerTableSorter()); - } - - /** - * Creates the columns for the sync viewer table. - */ - private void createColumns(Table table, TableLayout layout, TableViewer viewer) { - SelectionListener headerListener = SyncViewerTableSorter.getColumnListener(viewer); - // revision - TableColumn col = new TableColumn(table, SWT.NONE); - col.setResizable(true); - col.setText(Policy.bind("TeamSubscriberParticipantPage.7")); //$NON-NLS-1$ - col.addSelectionListener(headerListener); - layout.addColumnData(new ColumnWeightData(30, true)); - - // tags - col = new TableColumn(table, SWT.NONE); - col.setResizable(true); - col.setText(Policy.bind("TeamSubscriberParticipantPage.8")); //$NON-NLS-1$ - col.addSelectionListener(headerListener); - layout.addColumnData(new ColumnWeightData(50, true)); - } - - private void disposeChildren(Composite parent) { - // Null out the control of the busy cursor while we are switching viewers - Control[] children = parent.getChildren(); - for (int i = 0; i < children.length; i++) { - Control control = children[i]; - control.dispose(); - } - } - - private void handleOpen(OpenEvent event) { - openWithActions.openInCompareEditor(); - } - /** - * Handles a double-click event from the viewer. - * Expands or collapses a folder when double-clicked. - * - * @param event the double-click event - * @since 2.0 - */ - private void handleDoubleClick(DoubleClickEvent event) { - IStructuredSelection selection = (IStructuredSelection) event.getSelection(); - Object element = selection.getFirstElement(); - // Double-clicking should expand/collapse containers - if (viewer instanceof TreeViewer) { - TreeViewer tree = (TreeViewer)viewer; - if (tree.isExpandable(element)) { - tree.setExpandedState(element, !tree.getExpandedState(element)); - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.ui.part.IPage#setFocus() - */ - public void setFocus() { - if (viewer == null) return; - viewer.getControl().setFocus(); - } - - public StructuredViewer getViewer() { - return viewer; - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IWorkbenchPart#dispose() - */ - public void dispose() { - busyCursor.dispose(); - statusLine.dispose(); - } - - /* - * Return the current input for the view. - */ - public SubscriberInput getInput() { - return input; - } - - public void collapseAll() { - if (viewer == null || !(viewer instanceof AbstractTreeViewer)) return; - viewer.getControl().setRedraw(false); - ((AbstractTreeViewer)viewer).collapseToLevel(viewer.getInput(), TreeViewer.ALL_LEVELS); - viewer.getControl().setRedraw(true); - } - - /** - * This method enables "Show In" support for this view - * - * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) - */ - public Object getAdapter(Class key) { - if (key == IShowInSource.class) { - return new IShowInSource() { - public ShowInContext getShowInContext() { - StructuredViewer v = getViewer(); - if (v == null) return null; - return new ShowInContext(null, v.getSelection()); - } - }; - } - return null; - } - - /** - * Updates the message shown in the status line. - * - * @param selection the current selection - */ - private void updateStatusLine(IStructuredSelection selection) { - String msg = getStatusLineMessage(selection); - getSite().getActionBars().getStatusLineManager().setMessage(msg); - } - - /** - * Returns the message to show in the status line. - * - * @param selection the current selection - * @return the status line message - * @since 2.0 - */ - private String getStatusLineMessage(IStructuredSelection selection) { - if (selection.size() == 1) { - IResource resource = getResource(selection.getFirstElement()); - if (resource == null) { - return Policy.bind("SynchronizeView.12"); //$NON-NLS-1$ - } else { - return resource.getFullPath().makeRelative().toString(); - } - } - if (selection.size() > 1) { - return selection.size() + Policy.bind("SynchronizeView.13"); //$NON-NLS-1$ - } - return ""; //$NON-NLS-1$ - } - - private IResource getResource(Object object) { - return SyncSetContentProvider.getResource(object); - } - - public void selectAll() { - Viewer viewer = getViewer(); - if (viewer instanceof TableViewer) { - TableViewer table = (TableViewer)viewer; - table.getTable().selectAll(); - } else { - // Select All in a tree doesn't really work well - } - } - - private IPreferenceStore getStore() { - return TeamUIPlugin.getPlugin().getPreferenceStore(); - } - - /* (non-Javadoc) - * @see org.eclipse.ui.part.IPage#getControl() - */ - public Control getControl() { - return composite; - } - - /* (non-Javadoc) - * @see org.eclipse.ui.part.IPage#setActionBars(org.eclipse.ui.IActionBars) - */ - public void setActionBars(IActionBars actionBars) { - if(actionBars != null) { - IToolBarManager manager = actionBars.getToolBarManager(); - - // toolbar - manager.add(refreshAllAction); - manager.add(new Separator()); - manager.add(gotoNext); - manager.add(gotoPrevious); - manager.add(collapseAll); - manager.add(new Separator()); - - // view menu - updateViewMenu(actionBars); - - // status line - statusLine.fillActionBars(actionBars); - } - } - - private void updateViewMenu(IActionBars actionBars) { - IMenuManager menu = actionBars.getMenuManager(); - MenuManager layoutMenu = new MenuManager(Policy.bind("action.layout.label")); //$NON-NLS-1$ - layoutMenu.add(toggleLayoutTable); - layoutMenu.add(toggleLayoutTree); - MenuManager comparisonCriteria = new MenuManager(Policy.bind("action.comparisonCriteria.label")); //$NON-NLS-1$ - comparisonCriteriaGroup.addActionsToMenuMgr(comparisonCriteria); - workingSetGroup.fillActionBars(actionBars); - menu.add(new Separator()); - menu.add(comparisonCriteria); - menu.add(layoutMenu); - menu.add(new Separator()); - menu.add(showPreferences); - } - - /* (non-Javadoc) - * @see org.eclipse.ui.part.IPageBookViewPage#getSite() - */ - public IPageSite getSite() { - return this.site; - } - - /* (non-Javadoc) - * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) - */ - public void propertyChange(PropertyChangeEvent event) { - // Layout change - if(event.getProperty().equals(TeamSubscriberParticipant.P_SYNCVIEWPAGE_LAYOUT)) { - switchViewerType(((Integer)event.getNewValue()).intValue()); - // Direction mode change - } else if(event.getProperty().equals(TeamSubscriberParticipant.P_SYNCVIEWPAGE_MODE)) { - updateMode(((Integer)event.getNewValue()).intValue()); - // Working set changed via menu selection - notify participant and - // do all the real work when we get the next workset changed event - } else if(event.getProperty().equals(WorkingSetFilterActionGroup.CHANGE_WORKING_SET)) { - if(settingWorkingSet) return; - settingWorkingSet = true; - participant.setWorkingSet((IWorkingSet)event.getNewValue()); - settingWorkingSet = false; - // Working set changed programatically - } else if(event.getProperty().equals(TeamSubscriberParticipant.P_SYNCVIEWPAGE_WORKINGSET)) { - if(settingWorkingSet) return; - settingWorkingSet = true; - Object newValue = event.getNewValue(); - if (newValue instanceof IWorkingSet) { - workingSetGroup.setWorkingSet((IWorkingSet)newValue); - } else if (newValue == null) { - workingSetGroup.setWorkingSet(null); - } - settingWorkingSet = false; - // Change to showing of sync state in text labels preference - } else if(event.getProperty().equals(IPreferenceIds.SYNCVIEW_VIEW_SYNCINFO_IN_LABEL)) { - getViewer().refresh(true /* update labels */); - } - } - - private void updateMode(int mode) { - int[] modeFilter = BOTH_MODE_FILTER; - switch(mode) { - case TeamSubscriberParticipant.INCOMING_MODE: - modeFilter = INCOMING_MODE_FILTER; break; - case TeamSubscriberParticipant.OUTGOING_MODE: - modeFilter = OUTGOING_MODE_FILTER; break; - case TeamSubscriberParticipant.BOTH_MODE: - modeFilter = BOTH_MODE_FILTER; break; - case TeamSubscriberParticipant.CONFLICTING_MODE: - modeFilter = CONFLICTING_MODE_FILTER; break; - } - try { - input.setFilter( - new SyncInfoFilter.AndSyncInfoFilter( - new SyncInfoFilter[] { - new SyncInfoFilter.SyncInfoDirectionFilter(modeFilter), - new SyncInfoFilter.SyncInfoChangeTypeFilter(new int[] {SyncInfo.ADDITION, SyncInfo.DELETION, SyncInfo.CHANGE}), - new SyncInfoFilter.PseudoConflictFilter() - }), new NullProgressMonitor()); - } catch (TeamException e) { - Utils.handleError(getSite().getShell(), e, Policy.bind("SynchronizeView.16"), e.getMessage()); //$NON-NLS-1$ - } - } - - /** - * @return Returns the participant. - */ - public TeamSubscriberParticipant getParticipant() { - return participant; - } - - /** - * @return Returns the view. - */ - public ISynchronizeView getSynchronizeView() { - return view; - } -}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/actions/SubscriberAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/actions/SubscriberAction.java deleted file mode 100644 index 9a653f56a..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/actions/SubscriberAction.java +++ /dev/null @@ -1,101 +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.ui.synchronize.actions; - -import java.util.*; - -import org.eclipse.core.runtime.QualifiedName; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.internal.ui.TeamUIPlugin; -import org.eclipse.team.internal.ui.actions.TeamAction; -import org.eclipse.team.ui.synchronize.ITeamSubscriberParticipantNode; -import org.eclipse.ui.IViewActionDelegate; - -/** - * This is an abstract superclass for actions associated with a - * {@link TeamSubscriberParticipant}. It provides helper methods to - * access and filter selections that contain {@link ITeamSubscriberParticipantNode} - * instances. - * <p> - * It is optional for TeamSubscriberParticipant actions to subclass. - * </p> - * @since 3.0 - */ -public abstract class SubscriberAction extends TeamAction implements IViewActionDelegate { - - public static final QualifiedName SUBSCRIBER_JOB_TYPE = new QualifiedName(TeamUIPlugin.ID, "subcriber_job"); //$NON-NLS-1$ - - /** - * This method returns all instances of SynchronizeViewNode that are in the current - * selection. For a table view, this is any resource that is directly selected. - * For a tree view, this is any descendants of the selected resource that are - * contained in the view. - * - * @return the selected resources - */ - protected SyncInfo[] getSyncInfos() { - Object[] selected = ((IStructuredSelection)selection).toArray(); - Set result = new HashSet(); - for (int i = 0; i < selected.length; i++) { - Object object = selected[i]; - if (object instanceof ITeamSubscriberParticipantNode) { - ITeamSubscriberParticipantNode syncResource = (ITeamSubscriberParticipantNode) object; - SyncInfo[] infos = syncResource.getChildSyncInfos(); - result.addAll(Arrays.asList(infos)); - } - } - return (SyncInfo[]) result.toArray(new SyncInfo[result.size()]); - } - - /** - * The default enablement behavior for subscriber actions is to enable - * the action if there is at least one SyncInfo in the selection - * for which the action is enabled (determined by invoking - * <code>isEnabled(SyncInfo)</code>). - * @see org.eclipse.team.internal.ui.actions.TeamAction#isEnabled() - */ - protected boolean isEnabled() throws TeamException { - return (getFilteredSyncInfos().length > 0); - } - - /** - * Return true if the action should be enabled for the given SyncInfo. - * Default behavior is to use a SyncInfoFilter to determine if the action - * is enabled. - * - * @param info - * @return - */ - protected boolean select(SyncInfo info) { - return info != null && getSyncInfoFilter().select(info); - } - - protected SyncInfoFilter getSyncInfoFilter() { - return new SyncInfoFilter(); - } - - /** - * Return the selected SyncInfo for which this action is enabled. - * @return - */ - protected SyncInfo[] getFilteredSyncInfos() { - SyncInfo[] infos = getSyncInfos(); - List filtered = new ArrayList(); - for (int i = 0; i < infos.length; i++) { - SyncInfo info = infos[i]; - if (select(info)) - filtered.add(info); - } - return (SyncInfo[]) filtered.toArray(new SyncInfo[filtered.size()]); - } -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/actions/SyncInfoFilter.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/actions/SyncInfoFilter.java deleted file mode 100644 index 4f60d06d6..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/actions/SyncInfoFilter.java +++ /dev/null @@ -1,155 +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.ui.synchronize.actions; - -import org.eclipse.team.core.subscribers.SyncInfo; - -/** - * A SyncInfoFilter can be used to control, at a fine grain, {@link SyncInfo} - * instances in a SyncInfoSet. - * - * @see SyncInfoSet - * @since 3.0 - */ -public class SyncInfoFilter { - - public static SyncInfoFilter getDirectionAndChangeFilter(int direction, int change) { - return new AndSyncInfoFilter(new SyncInfoFilter[]{new SyncInfoDirectionFilter(direction), new SyncInfoChangeTypeFilter(change)}); - } - - public static abstract class CompoundSyncInfoFilter extends SyncInfoFilter { - protected SyncInfoFilter[] filters; - public CompoundSyncInfoFilter(SyncInfoFilter[] filters) { - this.filters = filters; - } - } - - /** - * Selects SyncInfo which match all child filters - */ - public static class AndSyncInfoFilter extends CompoundSyncInfoFilter { - public AndSyncInfoFilter(SyncInfoFilter[] filters) { - super(filters); - } - /* (non-Javadoc) - * @see org.eclipse.team.ccvs.syncviews.views.SyncSetFilter#select(org.eclipse.team.core.sync.SyncInfo) - */ - public boolean select(SyncInfo info) { - for (int i = 0; i < filters.length; i++) { - SyncInfoFilter filter = filters[i]; - if (!filter.select(info)) { - return false; - } - } - return true; - } - - } - - public static class AutomergableFilter extends SyncInfoFilter { - public boolean select(SyncInfo info) { - return (info.getKind() & SyncInfo.AUTOMERGE_CONFLICT) != 0; - } - } - - public static class PseudoConflictFilter extends SyncInfoFilter { - public boolean select(SyncInfo info) { - return info.getKind() != 0 && (info.getKind() & SyncInfo.PSEUDO_CONFLICT) == 0; - } - } - - /** - * Selects SyncInfo that match any of the child filters. - */ - public static class OrSyncInfoFilter extends CompoundSyncInfoFilter { - public OrSyncInfoFilter(SyncInfoFilter[] filters) { - super(filters); - } - /* (non-Javadoc) - * @see org.eclipse.team.ccvs.syncviews.views.SyncSetFilter#select(org.eclipse.team.core.sync.SyncInfo) - */ - public boolean select(SyncInfo info) { - for (int i = 0; i < filters.length; i++) { - SyncInfoFilter filter = filters[i]; - if (filter.select(info)) { - return true; - } - } - return false; - } - } - - public static class SyncInfoChangeTypeFilter extends SyncInfoFilter { - - private int[] changeFilters = new int[]{SyncInfo.ADDITION, SyncInfo.DELETION, SyncInfo.CHANGE}; - - public SyncInfoChangeTypeFilter(int[] changeFilters) { - this.changeFilters = changeFilters; - } - - public SyncInfoChangeTypeFilter(int change) { - this(new int[]{change}); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.team.ccvs.syncviews.views.SyncSetFilter#select(org.eclipse.team.core.sync.SyncInfo) - */ - public boolean select(SyncInfo info) { - int syncKind = info.getKind(); - for (int i = 0; i < changeFilters.length; i++) { - int filter = changeFilters[i]; - if ((syncKind & SyncInfo.CHANGE_MASK) == filter) - return true; - } - return false; - } - - } - - public static class SyncInfoDirectionFilter extends SyncInfoFilter { - - int[] directionFilters = new int[] {SyncInfo.OUTGOING, SyncInfo.INCOMING, SyncInfo.CONFLICTING}; - - public SyncInfoDirectionFilter(int[] directionFilters) { - this.directionFilters = directionFilters; - } - - public SyncInfoDirectionFilter(int direction) { - this(new int[] { direction }); - } - - /* (non-Javadoc) - * @see SyncSetFilter#select(org.eclipse.team.core.sync.SyncInfo) - */ - public boolean select(SyncInfo info) { - int syncKind = info.getKind(); - for (int i = 0; i < directionFilters.length; i++) { - int filter = directionFilters[i]; - if ((syncKind & SyncInfo.DIRECTION_MASK) == filter) - return true; - } - return false; - } - } - - /** - * Return true if the provided SyncInfo matches the filter. The default - * behavior it to include resources whose syncKind is non-zero. - * - * @param info - * @return - */ - public boolean select(SyncInfo info) { - return info.getKind() != 0; - } -}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/actions/SyncInfoSet.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/actions/SyncInfoSet.java deleted file mode 100644 index ab75b7e91..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/actions/SyncInfoSet.java +++ /dev/null @@ -1,214 +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.ui.synchronize.actions; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.eclipse.core.resources.IResource; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.ui.synchronize.actions.SyncInfoFilter.SyncInfoDirectionFilter; - -/** - * Convenience class for manipulating and searching sets of {@link SyncInfo} - * instances. - * - * @see SyncInfoFilter - * @since 3.0 - */ -public class SyncInfoSet { - - Set set = new HashSet(); - - public SyncInfoSet(SyncInfo[] infos) { - set.addAll(Arrays.asList(infos)); - } - /** - * Returns true if there are any conflicting nodes in the set, and - * false otherwise. - */ - public boolean hasConflicts() { - return hasNodes(new SyncInfoFilter.SyncInfoDirectionFilter(SyncInfo.CONFLICTING)); - } - - /** - * Returns true if this sync set has incoming changes. - * Note that conflicts are not considered to be incoming changes. - */ - public boolean hasIncomingChanges() { - return hasNodes(new SyncInfoDirectionFilter(SyncInfo.INCOMING)); - } - - /** - * Returns true if this sync set has outgoing changes. - * Note that conflicts are not considered to be outgoing changes. - */ - public boolean hasOutgoingChanges() { - return hasNodes(new SyncInfoDirectionFilter(SyncInfo.OUTGOING)); - } - - /** - * Returns true if this sync set has auto-mergeable conflicts. - */ - public boolean hasAutoMergeableConflicts() { - return hasNodes(new SyncInfoFilter.AutomergableFilter()); - } - - /** - * Removes all conflicting nodes from this set. - */ - public void removeConflictingNodes() { - rejectNodes(new SyncInfoDirectionFilter(SyncInfo.CONFLICTING)); - } - /** - * Removes all outgoing nodes from this set. - */ - public void removeOutgoingNodes() { - rejectNodes(new SyncInfoDirectionFilter(SyncInfo.OUTGOING)); - } - /** - * Removes all incoming nodes from this set. - */ - public void removeIncomingNodes() { - rejectNodes(new SyncInfoDirectionFilter(SyncInfo.INCOMING)); - } - - /** - * Removes all nodes from this set that are not auto-mergeable conflicts - */ - public void removeNonMergeableNodes() { - for (Iterator it = set.iterator(); it.hasNext();) { - SyncInfo node = (SyncInfo)it.next(); - if ((node.getKind() & SyncInfo.MANUAL_CONFLICT) != 0) { - it.remove(); - } else if ((node.getKind() & SyncInfo.DIRECTION_MASK) != SyncInfo.CONFLICTING) { - it.remove(); - } - } - } - - /** - * Indicate whether the set has nodes matching the given filter - */ - public boolean hasNodes(SyncInfoFilter filter) { - for (Iterator it = set.iterator(); it.hasNext();) { - SyncInfo info = (SyncInfo)it.next(); - if (info != null && filter.select(info)) { - return true; - } - } - return false; - } - - /** - * Removes all nodes from this set that do not match the given filter - */ - public void selectNodes(SyncInfoFilter filter) { - for (Iterator it = set.iterator(); it.hasNext();) { - SyncInfo info = (SyncInfo)it.next(); - if (info == null || !filter.select(info)) { - it.remove(); - } - } - } - - /** - * Removes all nodes from this set that match the given filter - */ - public void rejectNodes(SyncInfoFilter filter) { - for (Iterator it = set.iterator(); it.hasNext();) { - SyncInfo info = (SyncInfo)it.next(); - if (info != null && filter.select(info)) { - it.remove(); - } - } - } - - /** - * Return all nodes in this set that match the given filter - */ - public SyncInfo[] getNodes(SyncInfoFilter filter) { - List result = new ArrayList(); - for (Iterator it = set.iterator(); it.hasNext();) { - SyncInfo info = (SyncInfo)it.next(); - if (info != null && filter.select(info)) { - result.add(info); - } - } - return (SyncInfo[]) result.toArray(new SyncInfo[result.size()]); - } - - public SyncInfo[] getSyncInfos() { - return (SyncInfo[]) set.toArray(new SyncInfo[set.size()]); - } - - /** - * Returns the resources from all the nodes in this set. - */ - public IResource[] getResources() { - SyncInfo[] changed = getSyncInfos(); - IResource[] resources = new IResource[changed.length]; - for (int i = 0; i < changed.length; i++) { - resources[i] = changed[i].getLocal(); - } - return resources; - } - - public boolean isEmpty() { - return set.isEmpty(); - } - - public void removeResources(IResource[] resources) { - for (int i = 0; i < resources.length; i++) { - IResource resource = resources[i]; - removeResource(resource); - } - } - - public int size() { - return set.size(); - } - - public SyncInfo getNodeFor(IResource resource) { - for (Iterator it = set.iterator(); it.hasNext();) { - SyncInfo node = (SyncInfo)it.next(); - if (node.getLocal().equals(resource)) { - return node; - } - } - return null; - } - - public void addAll(SyncInfoSet set) { - SyncInfo[] resources = set.getSyncInfos(); - for (int i = 0; i < resources.length; i++) { - SyncInfo resource = resources[i]; - this.set.add(resource); - } - - } - - private void removeResource(IResource resource) { - for (Iterator it = set.iterator(); it.hasNext();) { - SyncInfo node = (SyncInfo)it.next(); - if (node.getLocal().equals(resource)) { - it.remove(); - // short-circuit the operation once a match is found - return; - } - } - } -} - diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/actions/package.html b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/actions/package.html deleted file mode 100644 index da6e3d510..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/actions/package.html +++ /dev/null @@ -1,14 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="Author" content="IBM"> - <title>Package-level Javadoc</title> -</head> -<body> -<p>Actions and utilities for use with the Eclipse Synchronize View.</p> -<h2>Package Specification</h2> -<p>This package contains actions that are used by subclasses of <b>TeamSubscriberParticipant</b>.</p> - -</body> -</html>
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/package.html b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/package.html index 6112f4106..b40bd2f51 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/package.html +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/package.html @@ -1,67 +1,47 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en"> <html> <head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="Author" content="IBM"> - <title>Package-level Javadoc</title> + <meta content="text/html; charset=iso-8859-1" + http-equiv="Content-Type"> + <meta content="IBM" name="Author"> + <title>Package-level Javadoc</title> </head> <body> <p>Application programming interfaces for interaction with the Eclipse Synchronize View.</p> <h2>Package Specification</h2> -<p>The Eclipse Team UI plug-in provides a set of classes and interfaces to support - a generic synchronize view that can show multiple synchronize participants. - This package contains a generic abstract synchronize participant that provides - the common functionality for synchronize participants. The basic model for the - Synchronize View APIs is the following:</p> +<p>The Eclipse Team UI plug-in provides a set of classes and interfaces +to support a generic synchronize view that can show multiple +synchronize participants. This package contains a generic abstract +synchronize participant that provides the common functionality for +synchronize participants. The basic model for the Synchronize View APIs +is the following:</p> <ul> - <li>A ISynchronizeManager manages registered synchronize participants. There - can be several instances of the same participant type.</li> - <li>A ISynchronizeParticipant is a logical representation of a connection between - workspace resources and a remote location used to shared those resources.</li> + <li>A ISynchronizeManager manages registered synchronize +participants. There can be several instances of the same participant +type.</li> + <li>A ISynchronizeParticipant is a logical representation of a +connection between workspace resources and a remote location used to +shared those resources.</li> <li>A ISynchronizeView is a page book view of participants.</li> - <li>A ISynchronizeParticipant must create a page that will be displayed in the - ISynchronizeView page book view.</li> - <li>The ISynchronizeView shows a drop-down of all registered participants and - allows switching between them.</li> - <li>A ISynchronizeParticipant can contribute actions to the toolbar, menus, - and view menu.</li> -</ul> -<p>Synchronize participants are declared by extending the <strong>synchronizeParticipants - </strong>extension point. There are two classes of synchronize participants: - <em>static </em>participants will be created when the synchronize view is created, - and <em>dynamic</em> participants that are created by user code at some other - time. A synchronize manager (<b>ISynchronizeManager</b>) manages all active - synchronize participants, and provides notification of participants which are - added and removed. Participants are displayed in a page book view. Each participant - implementation is reponsible for creating its page (<b>IPageBookView</b>), which - provides freedom of presentation to the synchronize view implementation. A single - participant may be displayed simultaneously in multiple synchronize views, and - in different workbench windows.</p> -<p>The class <b>TeamSubscriberParticipant</b> provides an implementation of a - synchronize participant that enables synchronization for a <b>TeamSubscriber</b>. - For providers that implement a <strong>TeamSubscriber</strong>, this is the - easiest method of integrating into the Synchronize View. The TeamSubscriberParticipant - provides a view of changes (incoming, outgoing, conflicting), modes for showing - only a subset of the changes, decorations for identifying the changes, and working - sets. Here are the steps for creating a participant based on the TeamSubscriberParticipant - implementation:</p> -<ul> - <li>Implement a concrete subclass of <strong>TeamSubscriber</strong> that will - provide the physical connection between the workspace resources and the remote - location that is used to share the resources.</li> - <li>Subclass <strong>TeamSubscriberParticipant</strong> and provide concrete - implementations for init(QualifiedName), saveState(), and optionally createPage().</li> - <li>To add actions to the context menu of the participant page you must create - a viewerContribution in your plugin.xml with the targetID field equal to that - of the qualifier part of the participant's type id. For example: - <pre><viewerContribution id="org.eclipse.myteamplugin.syncparticipant.actions" - targetID="org.eclipse.myteamplugin.syncparticipant"</pre> - </li> - <li>To add participant specific actions to the view's action bar, subclass TeamSubscriberParticipantPage - and implement setActionBars().</li> - <li>To add participant specific decorations to the viewer, subclass TeamSubscriberParticipantPage - and implement getLabelProvider().</li> + <li>A ISynchronizeParticipant must create a page that will be +displayed in the ISynchronizeView page book view.</li> + <li>The ISynchronizeView shows a drop-down of all registered +participants and allows switching between them.</li> + <li>A ISynchronizeParticipant can contribute actions to the toolbar, +menus, and view menu.</li> </ul> +<p>Synchronize participants are declared by extending the <strong>synchronizeParticipants +</strong>extension point. There are two classes of synchronize +participants: <em>static </em>participants will be created when the +synchronize view is created, and <em>dynamic</em> participants that +are created by user code at some other time. A synchronize manager (<b>ISynchronizeManager</b>) +manages all active synchronize participants, and provides notification +of participants which are added and removed. Participants are displayed +in a page book view. Each participant implementation is reponsible for +creating its page (<b>IPageBookView</b>), which provides freedom of +presentation to the synchronize view implementation. A single +participant may be displayed simultaneously in multiple synchronize +views, and in different workbench windows.</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/actions/DirectionFilterActionGroup.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/DirectionFilterActionGroup.java index b26dca918..3b76316c2 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/actions/DirectionFilterActionGroup.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/DirectionFilterActionGroup.java @@ -8,7 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.team.ui.synchronize.actions; +package org.eclipse.team.ui.synchronize.subscriber; import java.util.*; @@ -18,7 +18,6 @@ import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.team.internal.ui.Policy; import org.eclipse.team.internal.ui.Utils; -import org.eclipse.team.ui.synchronize.TeamSubscriberParticipant; import org.eclipse.ui.IActionBars; import org.eclipse.ui.actions.ActionGroup; @@ -28,9 +27,9 @@ import org.eclipse.ui.actions.ActionGroup; * button is active at a time. * <p> * When a modes changes a property change event is fired from the participant - * with a value of <code>TeamSubscriberParticipant.P_SYNCVIEWPAGE_MODE</code>. + * with a value of <code>SubscriberParticipant.P_SYNCVIEWPAGE_MODE</code>. * </p> - * @see TeamSubscriberParticipant + * @see SubscriberParticipant * @since 3.0 */ public class DirectionFilterActionGroup extends ActionGroup implements IPropertyChangeListener { @@ -42,7 +41,7 @@ public class DirectionFilterActionGroup extends ActionGroup implements IProperty private DirectionFilterAction outgoingMode; private DirectionFilterAction bothMode; private DirectionFilterAction conflictsMode; - private TeamSubscriberParticipant page; + private SubscriberParticipant page; private int supportedModes; @@ -63,8 +62,10 @@ public class DirectionFilterActionGroup extends ActionGroup implements IProperty // checkMode() is called because programatic checking of radio buttons doesn't // consider radio buttons, hence breaks the radio-button behavior. As a workaround // we have to manually check/uncheck the set instead. - checkMode(modeId); - page.setMode(modeId); + //checkMode(modeId); + if(isChecked()) { + page.setMode(modeId); + } } public int getModeId() { return modeId; @@ -73,19 +74,19 @@ public class DirectionFilterActionGroup extends ActionGroup implements IProperty /** * Creates a direction filter group with the given supported modes. The - * possible values for modes are defined by the {@link TeamSubscriberParticipant} + * possible values for modes are defined by the {@link SubscriberParticipant} * class. * - * @see TeamSubscriberParticipant#BOTH_MODE - * @see TeamSubscriberParticipant#OUTGOING_MODE - * @see TeamSubscriberParticipant#INCOMING_MODE - * @see TeamSubscriberParticipant#CONFLICTING_MODE - * @see TeamSubscriberParticipant#ALL_MODES + * @see SubscriberParticipant#BOTH_MODE + * @see SubscriberParticipant#OUTGOING_MODE + * @see SubscriberParticipant#INCOMING_MODE + * @see SubscriberParticipant#CONFLICTING_MODE + * @see SubscriberParticipant#ALL_MODES * * @param participant the participant showing this group * @param supportedModes the modes to be shown */ - public DirectionFilterActionGroup(TeamSubscriberParticipant participant, int supportedModes) { + public DirectionFilterActionGroup(SubscriberParticipant participant, int supportedModes) { this.supportedModes = supportedModes; this.page = participant; createActions(); @@ -98,23 +99,23 @@ public class DirectionFilterActionGroup extends ActionGroup implements IProperty */ private void createActions() { // Create the actions - if((supportedModes & TeamSubscriberParticipant.INCOMING_MODE) != 0) { - incomingMode = new DirectionFilterAction("action.directionFilterIncoming.", "org.eclipse.team.ui.syncview.incomingFilter", TeamSubscriberParticipant.INCOMING_MODE); //$NON-NLS-1$ //$NON-NLS-2$ + if((supportedModes & SubscriberParticipant.INCOMING_MODE) != 0) { + incomingMode = new DirectionFilterAction("action.directionFilterIncoming.", "org.eclipse.team.ui.syncview.incomingFilter", SubscriberParticipant.INCOMING_MODE); //$NON-NLS-1$ //$NON-NLS-2$ actions.add(incomingMode); } - if((supportedModes & TeamSubscriberParticipant.OUTGOING_MODE) != 0) { - outgoingMode = new DirectionFilterAction("action.directionFilterOutgoing.", "org.eclipse.team.ui.syncview.outgoingFilter", TeamSubscriberParticipant.OUTGOING_MODE); //$NON-NLS-1$ //$NON-NLS-2$ + if((supportedModes & SubscriberParticipant.OUTGOING_MODE) != 0) { + outgoingMode = new DirectionFilterAction("action.directionFilterOutgoing.", "org.eclipse.team.ui.syncview.outgoingFilter", SubscriberParticipant.OUTGOING_MODE); //$NON-NLS-1$ //$NON-NLS-2$ actions.add(outgoingMode); } - if((supportedModes & TeamSubscriberParticipant.BOTH_MODE) != 0) { - bothMode = new DirectionFilterAction("action.directionFilterBoth.", "org.eclipse.team.ui.syncview.bothFilter", TeamSubscriberParticipant.BOTH_MODE); //$NON-NLS-1$ //$NON-NLS-2$ + if((supportedModes & SubscriberParticipant.BOTH_MODE) != 0) { + bothMode = new DirectionFilterAction("action.directionFilterBoth.", "org.eclipse.team.ui.syncview.bothFilter", SubscriberParticipant.BOTH_MODE); //$NON-NLS-1$ //$NON-NLS-2$ actions.add(bothMode); } - if((supportedModes & TeamSubscriberParticipant.CONFLICTING_MODE) != 0) { - conflictsMode = new DirectionFilterAction("action.directionFilterConflicts.", "org.eclipse.team.ui.syncview.conflictsFilter", TeamSubscriberParticipant.CONFLICTING_MODE); //$NON-NLS-1$ //$NON-NLS-2$ + if((supportedModes & SubscriberParticipant.CONFLICTING_MODE) != 0) { + conflictsMode = new DirectionFilterAction("action.directionFilterConflicts.", "org.eclipse.team.ui.syncview.conflictsFilter", SubscriberParticipant.CONFLICTING_MODE); //$NON-NLS-1$ //$NON-NLS-2$ actions.add(conflictsMode); } } @@ -160,7 +161,7 @@ public class DirectionFilterActionGroup extends ActionGroup implements IProperty * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) */ public void propertyChange(PropertyChangeEvent event) { - if(event.getProperty().equals(TeamSubscriberParticipant.P_SYNCVIEWPAGE_MODE)) { + if(event.getProperty().equals(SubscriberParticipant.P_SYNCVIEWPAGE_MODE)) { Integer mode = (Integer)event.getNewValue(); checkMode(mode.intValue()); } diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/RefreshAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/RefreshAction.java new file mode 100644 index 000000000..5fbbbce53 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/RefreshAction.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * 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.ui.synchronize.subscriber; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.jobs.*; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.viewers.*; +import org.eclipse.team.core.subscribers.SubscriberSyncInfoCollector; +import org.eclipse.team.internal.ui.Policy; +import org.eclipse.team.internal.ui.Utils; +import org.eclipse.team.internal.ui.jobs.RefreshSubscriberJob; +import org.eclipse.team.internal.ui.synchronize.IRefreshSubscriberListener; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.progress.IWorkbenchSiteProgressService; + +/** + * A general refresh action that will refresh a subscriber in the background. + */ +public class RefreshAction extends Action { + + private ISelectionProvider selectionProvider; + private boolean refreshAll; + private SubscriberSyncInfoCollector collector; + private IRefreshSubscriberListener listener; + private String description; + private IWorkbenchSite workbenchSite; + + public RefreshAction(ISelectionProvider page, String description, SubscriberSyncInfoCollector collector, IRefreshSubscriberListener listener, boolean refreshAll) { + this.selectionProvider = page; + this.description = description; + this.collector = collector; + this.listener = listener; + this.refreshAll = refreshAll; + Utils.initAction(this, "action.refreshWithRemote."); //$NON-NLS-1$ + } + + public void run() { + ISelection selection = selectionProvider.getSelection(); + if(selection instanceof IStructuredSelection) { + IResource[] resources = Utils.getResources(((IStructuredSelection)selection).toArray()); + if (refreshAll || resources.length == 0) { + // If no resources are selected, refresh all the subscriber roots + resources = collector.getRoots(); + } + run(getWorkbenchSite(), description, resources, collector, listener); + } + } + + public static void run(IWorkbenchSite site, String description, IResource[] resources, final SubscriberSyncInfoCollector collector, IRefreshSubscriberListener listener) { + // Cancel the scheduled background refresh or any other refresh that is happening. + // The scheduled background refresh will restart automatically. + Platform.getJobManager().cancel(RefreshSubscriberJob.getFamily()); + RefreshSubscriberJob job = new RefreshSubscriberJob(Policy.bind("SyncViewRefresh.taskName", description), resources, collector); //$NON-NLS-1$ + if (listener != null) { + RefreshSubscriberJob.addRefreshListener(listener); + } + IProgressMonitor group = Platform.getJobManager().createProgressGroup(); + group.beginTask("Refreshing " + description, 100); + job.setProgressGroup(group, 70); + collector.setProgressGroup(group, 30); + + schedule(job, site); + job.addJobChangeListener(new JobChangeAdapter() { + public void done(IJobChangeEvent event) { + collector.setProgressGroup(null, 0); + } + }); + } + + public void setWorkbenchSite(IWorkbenchSite part) { + this.workbenchSite = part; + } + + public IWorkbenchSite getWorkbenchSite() { + return workbenchSite; + } + + private static void schedule(Job job, IWorkbenchSite site) { + if(site == null) { + job.schedule(); + } + IWorkbenchSiteProgressService siteProgress = (IWorkbenchSiteProgressService) site.getAdapter(IWorkbenchSiteProgressService.class); + if (siteProgress != null) { + siteProgress.schedule(job); + } + } +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/SubscriberPageDiffTreeViewerConfiguration.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/SubscriberPageDiffTreeViewerConfiguration.java new file mode 100644 index 000000000..c74e797aa --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/SubscriberPageDiffTreeViewerConfiguration.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * 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.ui.synchronize.subscriber; + +import org.eclipse.compare.structuremergeviewer.DiffNode; +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.viewers.*; +import org.eclipse.team.internal.ui.Policy; +import org.eclipse.team.internal.ui.synchronize.actions.*; +import org.eclipse.team.ui.synchronize.*; +import org.eclipse.team.ui.synchronize.viewers.*; + +/** + * Overrides the SyncInfoDiffViewerConfiguration to configure the diff viewer + * for the synchroniza view + */ +public class SubscriberPageDiffTreeViewerConfiguration extends TreeViewerAdvisor { + + private ISynchronizeView view; + private SubscriberParticipant participant; + private OpenWithActionGroup openWithActions; + private RefactorActionGroup refactorActions; + private TeamParticipantRefreshAction refreshSelectionAction; + + public SubscriberPageDiffTreeViewerConfiguration(ISynchronizeView view, SubscriberParticipant participant) { + super(participant.getId(), participant.getSubscriberSyncInfoCollector().getSyncInfoTree()); + this.view = view; + this.participant = participant; + } + + protected SubscriberParticipant getParticipant() { + return participant; + } + + protected void initializeActions(StructuredViewer treeViewer) { + super.initializeActions(treeViewer); + openWithActions = new OpenWithActionGroup(view, participant); + refactorActions = new RefactorActionGroup(view); + refreshSelectionAction = new TeamParticipantRefreshAction(treeViewer, participant, false /* refresh */); + refreshSelectionAction.setWorkbenchSite(view.getSite()); + } + + protected void fillContextMenu(StructuredViewer viewer, IMenuManager manager) { + openWithActions.fillContextMenu(manager); + refactorActions.fillContextMenu(manager); + manager.add(refreshSelectionAction); + manager.add(new Separator()); + super.fillContextMenu(viewer, manager); + } + + /* + * (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SyncInfoDiffTreeViewer#handleDoubleClick(org.eclipse.jface.viewers.DoubleClickEvent) + */ + protected void handleDoubleClick(StructuredViewer viewer, DoubleClickEvent event) { + IStructuredSelection selection = (IStructuredSelection) event.getSelection(); + DiffNode node = (DiffNode) selection.getFirstElement(); + if (node != null && node instanceof SyncInfoModelElement) { + SyncInfoModelElement syncNode = (SyncInfoModelElement) node; + IResource resource = syncNode.getResource(); + if (syncNode != null && resource != null && resource.getType() == IResource.FILE) { + openWithActions.openInCompareEditor(); + return; + } + } + // Double-clicking should expand/collapse containers + super.handleDoubleClick(viewer, event); + } + + protected void initializeListeners(StructuredViewer viewer) { + viewer.addSelectionChangedListener(new ISelectionChangedListener() { + + public void selectionChanged(SelectionChangedEvent event) { + updateStatusLine((IStructuredSelection) event.getSelection()); + } + }); + viewer.addOpenListener(new IOpenListener() { + + public void open(OpenEvent event) { + handleOpen(); + } + }); + super.initializeListeners(viewer); + } + + protected void handleOpen() { + openWithActions.openInCompareEditor(); + } + + /** + * Updates the message shown in the status line. + * @param selection + * the current selection + */ + private void updateStatusLine(IStructuredSelection selection) { + String msg = getStatusLineMessage(selection); + view.getViewSite().getActionBars().getStatusLineManager().setMessage(msg); + } + + /** + * Returns the message to show in the status line. + * @param selection + * the current selection + * @return the status line message + * @since 2.0 + */ + private String getStatusLineMessage(IStructuredSelection selection) { + if (selection.size() == 1) { + Object first = selection.getFirstElement(); + if (first instanceof SyncInfoModelElement) { + SyncInfoModelElement node = (SyncInfoModelElement) first; + IResource resource = node.getResource(); + if (resource == null) { + return node.getName(); + } else { + return resource.getFullPath().makeRelative().toString(); + } + } + } + if (selection.size() > 1) { + return selection.size() + Policy.bind("SynchronizeView.13"); //$NON-NLS-1$ + } + return ""; //$NON-NLS-1$ + } +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/SubscriberParticipant.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/SubscriberParticipant.java new file mode 100644 index 000000000..49db0e622 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/SubscriberParticipant.java @@ -0,0 +1,280 @@ +/******************************************************************************* + * 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.ui.synchronize.subscriber; + +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.team.core.subscribers.*; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.internal.ui.*; +import org.eclipse.team.internal.ui.synchronize.actions.TeamParticipantRefreshAction; +import org.eclipse.team.ui.TeamUI; +import org.eclipse.team.ui.synchronize.AbstractSynchronizeParticipant; +import org.eclipse.team.ui.synchronize.ISynchronizeView; +import org.eclipse.ui.*; +import org.eclipse.ui.part.IPageBookViewPage; + +/** + * A synchronize participant that displays synchronization information for local + * resources that are managed via a {@link Subscriber}. + * + * @since 3.0 + */ +public abstract class SubscriberParticipant extends AbstractSynchronizeParticipant implements IPropertyChangeListener { + + private SubscriberSyncInfoCollector collector; + + private SubscriberRefreshSchedule refreshSchedule; + + private int currentMode; + + private IWorkingSet workingSet; + + private ISynchronizeView view; + + private boolean starting = true; + + /** + * Key for settings in memento + */ + private static final String CTX_SUBSCRIBER_PARTICIPANT_SETTINGS = TeamUIPlugin.ID + ".TEAMSUBSRCIBERSETTINGS"; //$NON-NLS-1$ + + /** + * Key for schedule in memento + */ + private static final String CTX_SUBSCRIBER_SCHEDULE_SETTINGS = TeamUIPlugin.ID + ".TEAMSUBSRCIBER_REFRESHSCHEDULE"; //$NON-NLS-1$ + + /** + * Property constant indicating the mode of a page has changed. + */ + public static final String P_SYNCVIEWPAGE_WORKINGSET = TeamUIPlugin.ID + ".P_SYNCVIEWPAGE_WORKINGSET"; //$NON-NLS-1$ + + /** + * Property constant indicating the schedule of a page has changed. + */ + public static final String P_SYNCVIEWPAGE_SCHEDULE = TeamUIPlugin.ID + ".P_SYNCVIEWPAGE_SCHEDULE"; //$NON-NLS-1$ + + /** + * Property constant indicating the mode of a page has changed. + */ + public static final String P_SYNCVIEWPAGE_MODE = TeamUIPlugin.ID + ".P_SYNCVIEWPAGE_MODE"; //$NON-NLS-1$ + + /** + * Modes are direction filters for the view + */ + public final static int INCOMING_MODE = 0x1; + public final static int OUTGOING_MODE = 0x2; + public final static int BOTH_MODE = 0x4; + public final static int CONFLICTING_MODE = 0x8; + public final static int ALL_MODES = INCOMING_MODE | OUTGOING_MODE | CONFLICTING_MODE | BOTH_MODE; + + public final static int[] INCOMING_MODE_FILTER = new int[] {SyncInfo.CONFLICTING, SyncInfo.INCOMING}; + public final static int[] OUTGOING_MODE_FILTER = new int[] {SyncInfo.CONFLICTING, SyncInfo.OUTGOING}; + public final static int[] BOTH_MODE_FILTER = new int[] {SyncInfo.CONFLICTING, SyncInfo.INCOMING, SyncInfo.OUTGOING}; + public final static int[] CONFLICTING_MODE_FILTER = new int[] {SyncInfo.CONFLICTING}; + + public SubscriberParticipant() { + super(); + refreshSchedule = new SubscriberRefreshSchedule(this); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.sync.ISynchronizeViewPage#createPage(org.eclipse.team.ui.sync.ISynchronizeView) + */ + public final IPageBookViewPage createPage(ISynchronizeView view) { + this.view = view; + return doCreatePage(view); + } + + protected IPageBookViewPage doCreatePage(ISynchronizeView view) { + return new SubscriberParticipantPage(this, view); + } + + public void setMode(int mode) { + int oldMode = getMode(); + if(oldMode == mode) return; + currentMode = mode; + TeamUIPlugin.getPlugin().getPreferenceStore().setValue(IPreferenceIds.SYNCVIEW_SELECTED_MODE, mode); + updateMode(mode); + firePropertyChange(this, P_SYNCVIEWPAGE_MODE, new Integer(oldMode), new Integer(mode)); + } + + public int getMode() { + return currentMode; + } + + public void setRefreshSchedule(SubscriberRefreshSchedule schedule) { + this.refreshSchedule = schedule; + firePropertyChange(this, P_SYNCVIEWPAGE_SCHEDULE, null, schedule); + } + + public SubscriberRefreshSchedule getRefreshSchedule() { + return refreshSchedule; + } + + public void setWorkingSet(IWorkingSet set) { + IWorkingSet oldSet = workingSet; + if(collector != null) { + IResource[] resources = set != null ? Utils.getResources(set.getElements()) : new IResource[0]; + collector.setWorkingSet(resources); + firePropertyChange(this, P_SYNCVIEWPAGE_WORKINGSET, oldSet, set); + } + workingSet = set; + } + + public IWorkingSet getWorkingSet() { + return workingSet; + } + + public void refreshWithRemote(IResource[] resources) { + if((resources == null || resources.length == 0)) { + TeamParticipantRefreshAction.run(view.getSite(), collector.getWorkingSet(), this); + } else { + TeamParticipantRefreshAction.run(view.getSite(), resources, this); + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.sync.AbstractSynchronizeViewPage#dispose() + */ + public void dispose() { + refreshSchedule.dispose(); + TeamUI.removePropertyChangeListener(this); + collector.dispose(); + } + + /** + * Return the <code>SubscriberSyncInfoCollector</code> for the participant. + * This collector maintains the set of all out-of-sync resources for the subscriber. + * @return the <code>SubscriberSyncInfoCollector</code> for this participant + */ + public final SubscriberSyncInfoCollector getSubscriberSyncInfoCollector() { + return collector; + } + + protected void setSubscriber(Subscriber subscriber) { + collector = new SubscriberSyncInfoCollector(subscriber); + + // listen for global ignore changes + TeamUI.addPropertyChangeListener(this); + + preCollectingChanges(); + + collector.start(); + + // start the refresh now that a subscriber has been added + SubscriberRefreshSchedule schedule = getRefreshSchedule(); + if(schedule.isEnabled()) { + getRefreshSchedule().startJob(); + } + } + + /** + * This method is invoked just before the collector is started. + * This gives an opertunity to configure the collector parameters + * before collection starts. The default implementation sets the working + * set as returned by <code>getWorkingSet()</code> and sets the mode + * as returned by <code>getMode()</code>. + */ + protected void preCollectingChanges() { + if(workingSet != null) { + setWorkingSet(workingSet); + } + updateMode(getMode()); + } + + /** + * Get the <code>Subscriber</code> for this participant + * @return a <code>TamSubscriber</code> + */ + public Subscriber getSubscriber() { + return collector.getSubscriber(); + } + + /* (non-Javadoc) + * @see IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) + */ + public void propertyChange(PropertyChangeEvent event) { + if (event.getProperty().equals(TeamUI.GLOBAL_IGNORES_CHANGED)) { + collector.reset(); + } + } + + /** + * This method is invoked from <code>setMode</code> when the mode has changed. + * It sets the filter on the collector to show the <code>SyncInfo</code> + * appropriate for the mode. + * @param mode the new mode (one of <code>INCOMING_MODE_FILTER</code>, + * <code>OUTGOING_MODE_FILTER</code>, <code>CONFLICTING_MODE_FILTER</code> + * or <code>BOTH_MODE_FILTER</code>) + */ + protected void updateMode(int mode) { + if(collector != null) { + + int[] modeFilter = BOTH_MODE_FILTER; + switch(mode) { + case SubscriberParticipant.INCOMING_MODE: + modeFilter = INCOMING_MODE_FILTER; break; + case SubscriberParticipant.OUTGOING_MODE: + modeFilter = OUTGOING_MODE_FILTER; break; + case SubscriberParticipant.BOTH_MODE: + modeFilter = BOTH_MODE_FILTER; break; + case SubscriberParticipant.CONFLICTING_MODE: + modeFilter = CONFLICTING_MODE_FILTER; break; + } + + collector.setFilter( + new FastSyncInfoFilter.AndSyncInfoFilter( + new FastSyncInfoFilter[] { + new FastSyncInfoFilter.SyncInfoDirectionFilter(modeFilter) + })); + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.ISynchronizeParticipant#init(org.eclipse.ui.IMemento) + */ + public void init(IMemento memento) throws PartInitException { + if(memento != null) { + IMemento settings = memento.getChild(CTX_SUBSCRIBER_PARTICIPANT_SETTINGS); + if(settings != null) { + String set = settings.getString(P_SYNCVIEWPAGE_WORKINGSET); + String mode = settings.getString(P_SYNCVIEWPAGE_MODE); + SubscriberRefreshSchedule schedule = SubscriberRefreshSchedule.init(settings.getChild(CTX_SUBSCRIBER_SCHEDULE_SETTINGS), this); + setRefreshSchedule(schedule); + + if(set != null) { + IWorkingSet workingSet = PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSet(set); + if(workingSet != null) { + setWorkingSet(workingSet); + } + } + setMode(Integer.parseInt(mode)); + } + } else { + setMode(BOTH_MODE); + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.ISynchronizeParticipant#saveState(org.eclipse.ui.IMemento) + */ + public void saveState(IMemento memento) { + IMemento settings = memento.createChild(CTX_SUBSCRIBER_PARTICIPANT_SETTINGS); + IWorkingSet set = getWorkingSet(); + if(set != null) { + settings.putString(P_SYNCVIEWPAGE_WORKINGSET, getWorkingSet().getName()); + } + settings.putString(P_SYNCVIEWPAGE_MODE, Integer.toString(getMode())); + refreshSchedule.saveState(settings.createChild(CTX_SUBSCRIBER_SCHEDULE_SETTINGS)); + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/SubscriberParticipantPage.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/SubscriberParticipantPage.java new file mode 100644 index 000000000..f7a9c0b90 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/SubscriberParticipantPage.java @@ -0,0 +1,309 @@ +/******************************************************************************* + * 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.ui.synchronize.subscriber; + +import org.eclipse.compare.internal.INavigatable; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.action.*; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.*; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.*; +import org.eclipse.team.internal.ui.*; +import org.eclipse.team.internal.ui.synchronize.ChangesSection; +import org.eclipse.team.internal.ui.synchronize.ConfigureRefreshScheduleDialog; +import org.eclipse.team.internal.ui.synchronize.actions.*; +import org.eclipse.team.ui.synchronize.ISynchronizeView; +import org.eclipse.team.ui.synchronize.viewers.TreeViewerAdvisor; +import org.eclipse.ui.*; +import org.eclipse.ui.part.*; + +/** + * A synchronize view page that works with participants that are subclasses of + * {@link SubscriberParticipant}. It shows changes in the tree or table view + * and supports navigation, opening, and filtering changes. + * <p> + * Clients can subclass to extend the label decoration or add action bar + * contributions. For more extensive modifications, clients should create + * their own custom page. + * </p> + * @since 3.0 + */ +public class SubscriberParticipantPage implements IPageBookViewPage, IPropertyChangeListener, IAdaptable { + // Parent composite of this view. It is remembered so that we can dispose of its children when + // the viewer type is switched. + private Composite composite = null; + private ChangesSection changesSection; + private Viewer changesViewer; + private boolean settingWorkingSet = false; + + private ISynchronizeView view; + private SubscriberParticipant participant; + private IPageSite site; + + // Toolbar and status line actions for this page, note that context menu actions shown in + // the changes viewer are contributed via the viewer and not the page. + private NavigateAction gotoNext; + private NavigateAction gotoPrevious; + private Action configureSchedule; + private SyncViewerShowPreferencesAction showPreferences; + private TeamParticipantRefreshAction refreshAllAction; + private Action collapseAll; + private WorkingSetFilterActionGroup workingSetGroup; + private StatusLineContributionGroup statusLine; + private SubscriberPageDiffTreeViewerConfiguration configuration; + + /** + * Constructs a new SynchronizeView. + */ + public SubscriberParticipantPage(SubscriberParticipant page, ISynchronizeView view) { + this.participant = page; + this.view = view; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.IPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + composite = new Composite(parent, SWT.NONE); + //sc.setContent(composite); + GridLayout gridLayout= new GridLayout(); + gridLayout.makeColumnsEqualWidth= false; + gridLayout.marginWidth= 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + composite.setLayout(gridLayout); + GridData data = new GridData(GridData.FILL_BOTH); + data.grabExcessVerticalSpace = true; + composite.setLayoutData(data); + + // Create the changes section which, in turn, creates the changes viewer and its configuration + this.changesSection = new ChangesSection(composite, this); + this.changesViewer = createChangesViewer(changesSection.getComposite()); + changesSection.setViewer(changesViewer); + + // toolbar + INavigatable nav = new INavigatable() { + public boolean gotoDifference(boolean next) { + return configuration.navigate(next); + } + }; + gotoNext = new NavigateAction(view, nav, true /*next*/); + gotoPrevious = new NavigateAction(view, nav, false /*previous*/); + refreshAllAction = new TeamParticipantRefreshAction(getSite().getSelectionProvider(), getParticipant(), true /* refresh all */); + refreshAllAction.setWorkbenchSite(view.getSite()); + collapseAll = new Action() { + public void run() { + if (changesViewer == null || !(changesViewer instanceof AbstractTreeViewer)) return; + changesViewer.getControl().setRedraw(false); + ((AbstractTreeViewer)changesViewer).collapseToLevel(changesViewer.getInput(), TreeViewer.ALL_LEVELS); + changesViewer.getControl().setRedraw(true); + } + }; + Utils.initAction(collapseAll, "action.collapseAll."); //$NON-NLS-1$ + + configureSchedule = new Action() { + public void run() { + ConfigureRefreshScheduleDialog d = new ConfigureRefreshScheduleDialog( + getShell(), participant.getRefreshSchedule()); + d.setBlockOnOpen(false); + d.open(); + } + }; + Utils.initAction(configureSchedule, "action.configureSchedulel."); //$NON-NLS-1$ + + // view menu + workingSetGroup = new WorkingSetFilterActionGroup(getShell(), this, view, participant); + showPreferences = new SyncViewerShowPreferencesAction(getShell()); + statusLine = new StatusLineContributionGroup(getShell(), getParticipant(), workingSetGroup); + + participant.addPropertyChangeListener(this); + TeamUIPlugin.getPlugin().getPreferenceStore().addPropertyChangeListener(this); + participant.setMode(participant.getMode()); + } + + private Shell getShell() { + return view.getSite().getShell(); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite, org.eclipse.ui.IMemento) + */ + public void init(IPageSite site) throws PartInitException { + this.site = site; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.IPage#setFocus() + */ + public void setFocus() { + changesSection.setFocus(); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchPart#dispose() + */ + public void dispose() { + changesSection.dispose(); + configuration.dispose(); + } + + /* + * This method enables "Show In" support for this view + * + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + public Object getAdapter(Class key) { + if (key.equals(ISelectionProvider.class)) + return changesViewer; + if (key == IShowInSource.class) { + return new IShowInSource() { + public ShowInContext getShowInContext() { + StructuredViewer v = (StructuredViewer)changesViewer; + if (v == null) return null; + ISelection s = v.getSelection(); + if (s instanceof IStructuredSelection) { + Object[] resources = Utils.getResources(((IStructuredSelection)s).toArray()); + return new ShowInContext(null, new StructuredSelection(resources)); + } + return null; + } + }; + } + if (key == IShowInTargetList.class) { + return new IShowInTargetList() { + public String[] getShowInTargetIds() { + return new String[] { IPageLayout.ID_RES_NAV }; + } + + }; + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.IPage#getControl() + */ + public Control getControl() { + return composite; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.IPage#setActionBars(org.eclipse.ui.IActionBars) + */ + public void setActionBars(IActionBars actionBars) { + if(actionBars != null) { + IToolBarManager manager = actionBars.getToolBarManager(); + + // toolbar + manager.add(refreshAllAction); + manager.add(new Separator()); + if(gotoNext != null) { + manager.add(gotoNext); + manager.add(gotoPrevious); + } + manager.add(collapseAll); + manager.add(new Separator()); + + // view menu + IMenuManager menu = actionBars.getMenuManager(); + MenuManager layoutMenu = new MenuManager(Policy.bind("action.layout.label")); //$NON-NLS-1$ + MenuManager comparisonCriteria = new MenuManager(Policy.bind("action.comparisonCriteria.label")); //$NON-NLS-1$ + //comparisonCriteriaGroup.addActionsToMenuMgr(comparisonCriteria); + workingSetGroup.fillActionBars(actionBars); + menu.add(new Separator()); + menu.add(new Separator()); + menu.add(new Separator("others")); //$NON-NLS-1$ + menu.add(new Separator()); + menu.add(configureSchedule); + menu.add(new Separator()); + menu.add(showPreferences); + + // status line + statusLine.fillActionBars(actionBars); + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.IPageBookViewPage#getSite() + */ + public IPageSite getSite() { + return this.site; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) + */ + public void propertyChange(PropertyChangeEvent event) { + // Working set changed by user + if(event.getProperty().equals(WorkingSetFilterActionGroup.CHANGE_WORKING_SET)) { + if(settingWorkingSet) return; + settingWorkingSet = true; + participant.setWorkingSet((IWorkingSet)event.getNewValue()); + settingWorkingSet = false; + // Working set changed programatically + } else if(event.getProperty().equals(SubscriberParticipant.P_SYNCVIEWPAGE_WORKINGSET)) { + if(settingWorkingSet) return; + settingWorkingSet = true; + Object newValue = event.getNewValue(); + if (newValue instanceof IWorkingSet) { + workingSetGroup.setWorkingSet((IWorkingSet)newValue); + } else if (newValue == null) { + workingSetGroup.setWorkingSet(null); + } + settingWorkingSet = false; + // Change to showing of sync state in text labels preference + } else if(event.getProperty().equals(IPreferenceIds.SYNCVIEW_VIEW_SYNCINFO_IN_LABEL)) { + if(changesViewer instanceof StructuredViewer) { + ((StructuredViewer)changesViewer).refresh(true /* update labels */); + } + } + } + + /** + * @return Returns the participant. + */ + public SubscriberParticipant getParticipant() { + return participant; + } + + /** + * @return Returns the view. + */ + public ISynchronizeView getSynchronizeView() { + return view; + } + + private Viewer createChangesViewer(Composite parent) { + configuration = createSyncInfoSetCompareConfiguration(); + TreeViewer viewer = new TreeViewerAdvisor.NavigableTreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + GridData data = new GridData(GridData.FILL_BOTH); + viewer.getControl().setLayoutData(data); + configuration.initializeViewer(viewer); + getSite().setSelectionProvider(viewer); + return viewer; + } + + public TreeViewerAdvisor getViewerConfiguration() { + return configuration; + } + + public Viewer getViewer() { + return changesViewer; + } + + protected SubscriberPageDiffTreeViewerConfiguration createSyncInfoSetCompareConfiguration() { + return new SubscriberPageDiffTreeViewerConfiguration(getSynchronizeView(), getParticipant()); + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/SubscriberRefreshSchedule.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/SubscriberRefreshSchedule.java new file mode 100644 index 000000000..1b8a8c7f8 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/SubscriberRefreshSchedule.java @@ -0,0 +1,195 @@ +package org.eclipse.team.ui.synchronize.subscriber; + +import java.text.DateFormat; +import java.util.Date; + +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.team.core.synchronize.SyncInfo; +import org.eclipse.team.core.synchronize.SyncInfoSet; +import org.eclipse.team.internal.ui.Policy; +import org.eclipse.team.internal.ui.TeamUIPlugin; +import org.eclipse.team.internal.ui.jobs.RefreshSubscriberJob; +import org.eclipse.team.internal.ui.synchronize.IRefreshEvent; +import org.eclipse.team.internal.ui.synchronize.IRefreshSubscriberListener; +import org.eclipse.ui.IMemento; + +public class SubscriberRefreshSchedule { + private long refreshInterval = 3600; // 1 hour default + + private boolean enabled = false; + + private RefreshSubscriberJob job; + + private SubscriberParticipant participant; + + private IRefreshEvent lastRefreshEvent; + + /** + * Key for settings in memento + */ + private static final String CTX_REFRESHSCHEDULE_INTERVAL = TeamUIPlugin.ID + ".CTX_REFRESHSCHEDULE_INTERVAL"; //$NON-NLS-1$ + + /** + * Key for schedule in memento + */ + private static final String CTX_REFRESHSCHEDULE_ENABLED = TeamUIPlugin.ID + ".CTX_REFRESHSCHEDULE_ENABLED"; //$NON-NLS-1$ + + private IRefreshSubscriberListener refreshSubscriberListener = new IRefreshSubscriberListener() { + public void refreshStarted(IRefreshEvent event) { + } + public void refreshDone(final IRefreshEvent event) { + if (event.getSubscriber() == participant.getSubscriber()) { + lastRefreshEvent = event; + } + } + }; + + + public SubscriberRefreshSchedule(SubscriberParticipant participant) { + this.participant = participant; + RefreshSubscriberJob.addRefreshListener(refreshSubscriberListener); + } + + /** + * @return Returns the enabled. + */ + public boolean isEnabled() { + return enabled; + } + + /** + * @param enabled The enabled to set. + */ + public void setEnabled(boolean enabled, boolean allowedToStart) { + boolean wasEnabled = isEnabled(); + this.enabled = enabled; + if(enabled && ! wasEnabled) { + if(allowedToStart) { + startJob(); + } + } else { + stopJob(); + } + } + + /** + * @return Returns the refreshInterval. + */ + public long getRefreshInterval() { + return refreshInterval; + } + + public SubscriberParticipant getParticipant() { + return participant; + } + + /** + * @param refreshInterval The refreshInterval to set. + */ + public void setRefreshInterval(long refreshInterval) { + stopJob(); + this.refreshInterval = refreshInterval; + if(isEnabled()) { + startJob(); + } + } + + protected void startJob() { + SyncInfoSet set = participant.getSubscriberSyncInfoCollector().getSyncInfoTree(); + if(set == null) { + return; + } + if(job == null) { + job = new RefreshSubscriberJob(Policy.bind("RefreshSchedule.14", participant.getName(), getRefreshIntervalAsString()), participant.getSubscriberSyncInfoCollector()); //$NON-NLS-1$ + } else if(job.getState() != Job.NONE){ + stopJob(); + } + job.setRestartOnCancel(true); + job.setReschedule(true); + job.schedule(getRefreshInterval()); + } + + protected void stopJob() { + if(job != null) { + job.setRestartOnCancel(false /* don't restart the job */); + job.setReschedule(false); + job.cancel(); + job = null; + } + } + + public void dispose() { + stopJob(); + RefreshSubscriberJob.removeRefreshListener(refreshSubscriberListener); + } + + public void saveState(IMemento memento) { + memento.putString(CTX_REFRESHSCHEDULE_ENABLED, Boolean.toString(enabled)); + memento.putInteger(CTX_REFRESHSCHEDULE_INTERVAL, (int)refreshInterval); + } + + public static SubscriberRefreshSchedule init(IMemento memento, SubscriberParticipant participant) { + SubscriberRefreshSchedule schedule = new SubscriberRefreshSchedule(participant); + if(memento != null) { + String enabled = memento.getString(CTX_REFRESHSCHEDULE_ENABLED); + int interval = memento.getInteger(CTX_REFRESHSCHEDULE_INTERVAL).intValue(); + schedule.setRefreshInterval(interval); + schedule.setEnabled("true".equals(enabled) ? true : false, false /* don't start job */); //$NON-NLS-1$ + } + // Use the defaults if a schedule hasn't been saved or can't be found. + return schedule; + } + + public static String refreshEventAsString(IRefreshEvent event) { + if(event == null) { + return Policy.bind("SyncViewPreferencePage.lastRefreshRunNever"); //$NON-NLS-1$ + } + long stopMills = event.getStopTime(); + long startMills = event.getStartTime(); + StringBuffer text = new StringBuffer(); + if(stopMills <= 0) { + text.append(Policy.bind("SyncViewPreferencePage.lastRefreshRunNever")); //$NON-NLS-1$ + } else { + Date lastTimeRun = new Date(stopMills); + text.append(DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(lastTimeRun)); + } + SyncInfo[] changes = event.getChanges(); + if (changes.length != 0) { + text.append(Policy.bind("RefreshSchedule.6", Integer.toString(changes.length))); //$NON-NLS-1$ + } else { + text.append(Policy.bind("RefreshSchedule.7")); //$NON-NLS-1$ + } + return text.toString(); + } + + public String getScheduleAsString() { + if(! isEnabled()) { + return Policy.bind("RefreshSchedule.8"); //$NON-NLS-1$ + } + return getRefreshIntervalAsString(); + } + + public IRefreshEvent getLastRefreshEvent() { + return lastRefreshEvent; + } + + private String getRefreshIntervalAsString() { + boolean hours = false; + long seconds = getRefreshInterval(); + if(seconds <= 60) { + seconds = 60; + } + long minutes = seconds / 60; + if(minutes >= 60) { + minutes = minutes / 60; + hours = true; + } + String unit; + if(minutes >= 1) { + unit = (hours ? Policy.bind("RefreshSchedule.9") : Policy.bind("RefreshSchedule.10")); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + unit = (hours ? Policy.bind("RefreshSchedule.11") : Policy.bind("RefreshSchedule.12")); //$NON-NLS-1$ //$NON-NLS-2$ + } + return Policy.bind("RefreshSchedule.13", Long.toString(minutes), unit); //$NON-NLS-1$ + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/package.html b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/package.html new file mode 100644 index 000000000..729b92e03 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/subscriber/package.html @@ -0,0 +1,43 @@ +<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta content="text/html; charset=iso-8859-1" + http-equiv="Content-Type"> + <meta content="IBM" name="Author"> + <title>Package-level Javadoc</title> +</head> +<body> +<p>Actions and utilities for use with the Eclipse Synchronize View.</p> +<h2>Package Specification</h2> +<p>This package contains actions that are used by subclasses of <b>TeamSubscriberParticipant</b>. +<br> +</p> +<p>The class <b>TeamSubscriberParticipant</b> provides an +implementation of a synchronize participant that enables +synchronization for a <b>Subscriber</b>. For providers that implement +a <strong>Subscriber</strong>, this is the easiest method of +integrating into the Synchronize View. The TeamSubscriberParticipant +provides a view of changes (incoming, outgoing, conflicting), modes for +showing only a subset of the changes, decorations for identifying the +changes, and working sets. Here are the steps for creating a +participant based on the TeamSubscriberParticipant implementation:</p> +<ul> + <li>Implement a concrete subclass of <strong>TeamSubscriber</strong> +that will provide the physical connection between the workspace +resources and the remote location that is used to share the resources.</li> + <li>Subclass <strong>TeamSubscriberParticipant</strong> and provide +concrete implementations for init(QualifiedName), saveState(), and +optionally createPage().</li> + <li>To add actions to the context menu of the participant page you +must create a viewerContribution in your plugin.xml with the targetID +field equal to that of the qualifier part of the participant's type id. +For example: + <pre><viewerContribution id="org.eclipse.myteamplugin.syncparticipant.actions" <br> targetID="org.eclipse.myteamplugin.syncparticipant"</pre> + </li> + <li>To add participant specific actions to the view's action bar, +subclass TeamSubscriberParticipantPage and implement setActionBars().</li> + <li>To add participant specific decorations to the viewer, subclass +TeamSubscriberParticipantPage and implement getLabelProvider().</li> +</ul> +</body> +</html> diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/CompressedFoldersModelProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/CompressedFoldersModelProvider.java new file mode 100644 index 000000000..2480c5f61 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/CompressedFoldersModelProvider.java @@ -0,0 +1,281 @@ +/******************************************************************************* + * 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.ui.synchronize.viewers; + +import java.util.*; + +import org.eclipse.compare.structuremergeviewer.IDiffContainer; +import org.eclipse.compare.structuremergeviewer.IDiffElement; +import org.eclipse.core.resources.*; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.internal.ui.TeamUIPlugin; +import org.eclipse.team.ui.ISharedImages; + +public class CompressedFoldersModelProvider extends HierarchicalModelProvider { + + protected class UnchangedCompressedDiffNode extends UnchangedResourceModelElement { + public UnchangedCompressedDiffNode(IDiffContainer parent, IResource resource) { + super(parent, resource); + } + + /* (non-Javadoc) + * @see org.eclipse.compare.structuremergeviewer.DiffNode#getName() + */ + public String getName() { + IResource resource = getResource(); + return resource.getProjectRelativePath().toString(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SyncInfoModelElement#getImageDescriptor(java.lang.Object) + */ + public ImageDescriptor getImageDescriptor(Object object) { + return TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_COMPRESSED_FOLDER); + } + } + + /** + * A compressed folder appears under a project and contains out-of-sync resources + */ + public class CompressedFolderDiffNode extends SyncInfoModelElement { + + public CompressedFolderDiffNode(IDiffContainer parent, SyncInfo info) { + super(parent, info); + } + + /* (non-Javadoc) + * @see org.eclipse.compare.structuremergeviewer.DiffNode#getName() + */ + public String getName() { + IResource resource = getResource(); + return resource.getProjectRelativePath().toString(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SyncInfoModelElement#getImageDescriptor(java.lang.Object) + */ + public ImageDescriptor getImageDescriptor(Object object) { + return TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_COMPRESSED_FOLDER); + } + } + + public CompressedFoldersModelProvider(SyncInfoTree set) { + super(set); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SyncInfoDiffNodeRoot#getSorter() + */ + public ViewerSorter getViewerSorter() { + return new SynchronizeModelElementSorter() { + protected int compareNames(IResource resource1, IResource resource2) { + if (resource1.getType() == IResource.FOLDER && resource2.getType() == IResource.FOLDER) { + return collator.compare(resource1.getProjectRelativePath().toString(), resource2.getProjectRelativePath().toString()); + } + return super.compareNames(resource1, resource2); + } + }; + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.viewers.HierarchicalModelProvider#createModelObjects(org.eclipse.compare.structuremergeviewer.DiffNode) + */ + protected IDiffElement[] createModelObjects(SynchronizeModelElement container) { + IResource resource = null; + if (container == getRoot()) { + resource = ResourcesPlugin.getWorkspace().getRoot(); + } else { + resource = container.getResource(); + } + if(resource != null) { + if (resource.getType() == IResource.PROJECT) { + return getProjectChildren(container, (IProject)resource); + } + if (resource.getType() == IResource.FOLDER) { + return getFolderChildren(container, resource); + } + } + return super.createModelObjects(container); + } + + private IDiffElement[] getFolderChildren(SynchronizeModelElement parent, IResource resource) { + // Folders will only contain out-of-sync children + IResource[] children = getSyncInfoTree().members(resource); + List result = new ArrayList(); + for (int i = 0; i < children.length; i++) { + IResource child = children[i]; + if (child.getType() == IResource.FILE) { + result.add(createModelObject(parent, child)); + } + } + return (IDiffElement[])result.toArray(new IDiffElement[result.size()]); + } + + private IDiffElement[] getProjectChildren(SynchronizeModelElement parent, IProject project) { + // The out-of-sync elements could possibly include the project so the code + // below is written to ignore the project + SyncInfo[] outOfSync = getSyncInfoTree().getSyncInfos(project, IResource.DEPTH_INFINITE); + Set result = new HashSet(); + Set resourcesToShow = new HashSet(); + for (int i = 0; i < outOfSync.length; i++) { + SyncInfo info = outOfSync[i]; + IResource local = info.getLocal(); + if (local.getProjectRelativePath().segmentCount() == 1 && local.getType() == IResource.FILE) { + resourcesToShow.add(local); + } else { + if (local.getType() == IResource.FILE) { + resourcesToShow.add(local.getParent()); + } else if (local.getType() == IResource.FOLDER){ + resourcesToShow.add(local); + } + } + } + for (Iterator iter = resourcesToShow.iterator(); iter.hasNext();) { + IResource resource = (IResource) iter.next(); + result.add(createModelObject(parent, resource)); + } + + return (IDiffElement[])result.toArray(new IDiffElement[result.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.views.HierarchicalModelProvider#createChildNode(org.eclipse.compare.structuremergeviewer.DiffNode, org.eclipse.core.resources.IResource) + */ + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.viewers.HierarchicalModelProvider#createModelObject(org.eclipse.compare.structuremergeviewer.DiffNode, org.eclipse.core.resources.IResource) + */ + protected SynchronizeModelElement createModelObject(SynchronizeModelElement parent, IResource resource) { + if (resource.getType() == IResource.FOLDER) { + SyncInfo info = getSyncInfoTree().getSyncInfo(resource); + SynchronizeModelElement newNode; + if(info != null) { + newNode = new CompressedFolderDiffNode(parent, info); + } else { + newNode = new UnchangedCompressedDiffNode(parent, resource); + } + addToViewer(newNode); + return newNode; + } + return super.createModelObject(parent, resource); + } + + /** + * Update the viewer for the sync set additions in the provided event. + * This method is invoked by <code>handleChanges(ISyncInfoSetChangeEvent)</code>. + * Subclasses may override. + * @param event + */ + protected void handleResourceAdditions(ISyncInfoTreeChangeEvent event) { + SyncInfo[] infos = event.getAddedResources(); + for (int i = 0; i < infos.length; i++) { + SyncInfo info = infos[i]; + addResource(info); + } + } + + private void addResource(SyncInfo info) { + IResource local = info.getLocal(); + SynchronizeModelElement existingNode = getModelObject(local); + if (existingNode == null) { + if (local.getType() == IResource.FILE) { + SynchronizeModelElement parentNode = getModelObject(local.getParent()); + if (parentNode == null) { + SynchronizeModelElement projectNode = getModelObject(local.getProject()); + if (projectNode == null) { + projectNode = createModelObject(getRoot(), local.getProject()); + } + if (local.getParent().getType() == IResource.PROJECT) { + parentNode = projectNode; + } else { + parentNode = createModelObject(projectNode, local.getParent()); + } + } + createModelObject(parentNode, local); + } else { + SynchronizeModelElement projectNode = getModelObject(local.getProject()); + if (projectNode == null) { + projectNode = createModelObject(getRoot(), local.getProject()); + } + createModelObject(projectNode, local); + } + } else { + // Either The folder node was added as the parent of a newly added out-of-sync file + // or the file was somehow already there so just refresh + handleChange(existingNode, info); + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.sync.views.SyncSetContentProvider#handleResourceRemovals(org.eclipse.team.internal.ui.sync.views.SyncSetChangedEvent) + */ + protected void handleResourceRemovals(ISyncInfoTreeChangeEvent event) { + IResource[] roots = event.getRemovedSubtreeRoots(); + + // First, deal with any projects that have been removed + List removedProjects = new ArrayList(); + for (int i = 0; i < roots.length; i++) { + IResource resource = roots[i]; + if (resource.getType() == IResource.PROJECT) { + removeFromViewer(resource); + removedProjects.add(resource); + } + } + + IResource[] resources = event.getRemovedResources(); + for (int i = 0; i < resources.length; i++) { + IResource resource = resources[i]; + if (!removedProjects.contains(resource.getProject())) { + if (resource.getType() == IResource.FILE) { + if (isCompressedParentEmpty(resource)) { + // The parent compressed folder is also empty so remove it + removeFromViewer(resource.getParent()); + } else { + removeFromViewer(resource); + } + } else { + // A folder has been removed (i.e. is in-sync) + // but may still contain children + removeFromViewer(resource); + if (hasFileMembers((IContainer)resource)) { + createModelObject(getModelObject(resource.getProject()), resource); + buildModelObjects(getModelObject(resource)); + } + } + } + } + } + + private boolean isCompressedParentEmpty(IResource resource) { + IContainer parent = resource.getParent(); + if (parent == null + || parent.getType() == IResource.ROOT + || parent.getType() == IResource.PROJECT) { + return false; + } + return !hasFileMembers(parent); + } + + private boolean hasFileMembers(IContainer parent) { + // Check if the sync set has any file children of the parent + IResource[] members = getSyncInfoTree().members(parent); + for (int i = 0; i < members.length; i++) { + IResource member = members[i]; + if (member.getType() == IResource.FILE) { + return true; + } + } + // The parent does not contain any files + return false; + } +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/HierarchicalModelProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/HierarchicalModelProvider.java new file mode 100644 index 000000000..873abbbae --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/HierarchicalModelProvider.java @@ -0,0 +1,570 @@ +/******************************************************************************* + * 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.ui.synchronize.viewers; + +import java.util.*; + +import org.eclipse.compare.structuremergeviewer.IDiffContainer; +import org.eclipse.compare.structuremergeviewer.IDiffElement; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.*; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.swt.widgets.Control; +import org.eclipse.team.core.ITeamStatus; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.internal.core.Assert; +import org.eclipse.team.internal.ui.TeamUIPlugin; +import org.eclipse.ui.progress.UIJob; +import org.eclipse.team.internal.ui.Policy; + +/** + * An input that can be used with both {@link } and + * {@link }. The + * job of this input is to create the logical model of the contents of the + * sync set for displaying to the user. The created logical model must diff + * nodes. + * <p> + * 1. First, prepareInput is called to initialize the model with the given sync + * set. Building the model occurs in the ui thread. + * 2. The input must react to changes in the sync set and adjust its diff node + * model then update the viewer. In effect mediating between the sync set + * changes and the model shown to the user. This happens in the ui thread. + * </p> + * NOT ON DEMAND - model is created then maintained! + * @since 3.0 + */ +public class HierarchicalModelProvider extends SynchronizeModelProvider implements ISyncInfoSetChangeListener { + + // Map from resources to model objects. This allows effecient lookup + // of model objects based on changes occuring to resources. + private Map resourceMap = Collections.synchronizedMap(new HashMap()); + + // The viewer this input is being displayed in + private AbstractTreeViewer viewer; + + // Flasg to indicate if tree control should be updated while + // building the model. + private boolean refreshViewer; + + private RootDiffNode root; + + private SyncInfoTree set; + + private Set pendingLabelUpdates = new HashSet(); + + private LabelUpdateJob labelUpdater = new LabelUpdateJob(); + + class LabelUpdateJob extends UIJob { + public static final int BATCH_WAIT_INCREMENT = 100; + Set nodes = new HashSet(); + public LabelUpdateJob() { + super(Policy.bind("HierarchicalModelProvider.0")); //$NON-NLS-1$ + setSystem(true); + } + public IStatus runInUIThread(IProgressMonitor monitor) { + Object[] updates; + synchronized(nodes) { + updates = nodes.toArray(new Object[nodes.size()]); + nodes.clear(); + } + if (canUpdateViewer()) { + AbstractTreeViewer tree = getTreeViewer(); + tree.update(updates, null); + } + schedule(BATCH_WAIT_INCREMENT); + return Status.OK_STATUS; + } + public void add(Object node, boolean isBusy) { + synchronized(nodes) { + nodes.add(node); + } + if (isBusy) { + schedule(BATCH_WAIT_INCREMENT); + } else { + // Wait when unbusying to give the events a chance to propogate through + // the collector + schedule(BATCH_WAIT_INCREMENT * 10); + } + } + public boolean shouldRun() { + return !nodes.isEmpty(); + } + } + + private IPropertyChangeListener listener = new IPropertyChangeListener() { + public void propertyChange(final PropertyChangeEvent event) { + if (event.getProperty() == SynchronizeModelElement.BUSY_PROPERTY) { + labelUpdater.add(event.getSource(), ((Boolean)event.getNewValue()).booleanValue()); + } + } + }; + + /** + * Create an input based on the provide sync set. The input is not initialized + * until <code>prepareInput</code> is called. + * + * @param set the sync set used as the basis for the model created by this input. + */ + public HierarchicalModelProvider(SyncInfoTree set) { + Assert.isNotNull(set); + this.root = new RootDiffNode(); + this.set = set; + } + + /** + * Return the model object (i.e. an instance of <code>SyncInfoModelElement</code> + * or one of its subclasses) for the given IResource. + * @param resource + * the resource + * @return the <code>SyncInfoModelElement</code> for the given resource + */ + protected SynchronizeModelElement getModelObject(IResource resource) { + return (SynchronizeModelElement) resourceMap.get(resource); + } + + /** + * Return the <code>AbstractTreeViewer</code> asociated with this content + * provider or <code>null</code> if the viewer is not of the proper type. + * @return + */ + public AbstractTreeViewer getTreeViewer() { + return viewer; + } + + public void setViewer(StructuredViewer viewer) { + Assert.isTrue(viewer instanceof AbstractTreeViewer); + this.viewer = (AbstractTreeViewer)viewer; + } + + public ViewerSorter getViewerSorter() { + return new SynchronizeModelElementSorter(); + } + + /** + * Builds the viewer model based on the contents of the sync set. + */ + public SynchronizeModelElement prepareInput(IProgressMonitor monitor) { + // Connect to the sync set which will register us as a listener and give us a reset event + // in a background thread + getSyncInfoTree().connect(this, monitor); + return getRoot(); + } + + /** + * Dispose of the builder + */ + public void dispose() { + resourceMap.clear(); + getSyncInfoTree().removeSyncSetChangedListener(this); + } + + /* + * (non-Javadoc) + * @see org.eclipse.team.ccvs.syncviews.views.ISyncSetChangedListener#syncSetChanged() + */ + public void syncInfoChanged(final ISyncInfoSetChangeEvent event, IProgressMonitor monitor) { + if (! (event instanceof ISyncInfoTreeChangeEvent)) { + reset(); + } else { + final Control ctrl = viewer.getControl(); + if (ctrl != null && !ctrl.isDisposed()) { + ctrl.getDisplay().syncExec(new Runnable() { + public void run() { + if (!ctrl.isDisposed()) { + BusyIndicator.showWhile(ctrl.getDisplay(), new Runnable() { + public void run() { + handleChanges((ISyncInfoTreeChangeEvent)event); + getRoot().fireChanges(); + } + }); + } + } + }); + } + } + } + + /** + * For each node create children based on the contents of + * @param node + * @return + */ + protected IDiffElement[] buildModelObjects(SynchronizeModelElement node) { + IDiffElement[] children = createModelObjects(node); + for (int i = 0; i < children.length; i++) { + IDiffElement element = children[i]; + if (element instanceof SynchronizeModelElement) { + buildModelObjects((SynchronizeModelElement) element); + } + } + return children; + } + + /** + * Invoked by the <code>buildModelObject</code> method to create + * the childen of the given node. This method can be overriden + * by subclasses but subclasses should inv + * @param container + * @return + */ + protected IDiffElement[] createModelObjects(SynchronizeModelElement container) { + IResource resource = null; + if (container == getRoot()) { + resource = ResourcesPlugin.getWorkspace().getRoot(); + } else { + resource = container.getResource(); + } + if(resource != null) { + SyncInfoTree infoTree = getSyncInfoTree(); + IResource[] children = infoTree.members(resource); + SynchronizeModelElement[] nodes = new SynchronizeModelElement[children.length]; + for (int i = 0; i < children.length; i++) { + nodes[i] = createModelObject(container, children[i]); + } + return nodes; + } + return new IDiffElement[0]; + } + + protected SynchronizeModelElement createModelObject(SynchronizeModelElement parent, IResource resource) { + SyncInfo info = getSyncInfoTree().getSyncInfo(resource); + SynchronizeModelElement newNode; + if(info != null) { + newNode = new SyncInfoModelElement(parent, info); + } else { + newNode = new UnchangedResourceModelElement(parent, resource); + } + addToViewer(newNode); + return newNode; + } + + /** + * Clear the model objects from the diff tree, cleaning up any cached state + * (such as resource to model object map). This method recurses deeply on + * the tree to allow the cleanup of any cached state for the children as + * well. + * @param node + * the root node + */ + protected void clearModelObjects(SynchronizeModelElement node) { + IDiffElement[] children = node.getChildren(); + for (int i = 0; i < children.length; i++) { + IDiffElement element = children[i]; + if (element instanceof SynchronizeModelElement) { + clearModelObjects((SynchronizeModelElement) element); + } + } + IResource resource = node.getResource(); + if (resource != null) { + unassociateDiffNode(resource); + } + IDiffContainer parent = node.getParent(); + if (parent != null) { + parent.removeToRoot(node); + } + } + + /** + * Invokes <code>getModelObject(Object)</code> on an array of resources. + * @param resources + * the resources + * @return the model objects for the resources + */ + protected Object[] getModelObjects(IResource[] resources) { + Object[] result = new Object[resources.length]; + for (int i = 0; i < resources.length; i++) { + result[i] = getModelObject(resources[i]); + } + return result; + } + + protected void associateDiffNode(SynchronizeModelElement node) { + IResource resource = node.getResource(); + if(resource != null) { + resourceMap.put(resource, node); + } + } + + protected void unassociateDiffNode(IResource resource) { + resourceMap.remove(resource); + } + + /** + * Handle the changes made to the viewer's <code>SyncInfoSet</code>. + * This method delegates the changes to the three methods <code>handleResourceChanges(ISyncInfoSetChangeEvent)</code>, + * <code>handleResourceRemovals(ISyncInfoSetChangeEvent)</code> and + * <code>handleResourceAdditions(ISyncInfoSetChangeEvent)</code>. + * @param event + * the event containing the changed resourcses. + */ + protected void handleChanges(ISyncInfoTreeChangeEvent event) { + try { + viewer.getControl().setRedraw(false); + handleResourceChanges(event); + handleResourceRemovals(event); + handleResourceAdditions(event); + firePendingLabelUpdates(); + } finally { + viewer.getControl().setRedraw(true); + } + } + + /** + * Update the viewer for the sync set additions in the provided event. This + * method is invoked by <code>handleChanges(ISyncInfoSetChangeEvent)</code>. + * Subclasses may override. + * @param event + */ + protected void handleResourceAdditions(ISyncInfoTreeChangeEvent event) { + IResource[] added = event.getAddedSubtreeRoots(); + addResources(added); + } + + /** + * Update the viewer for the sync set changes in the provided event. This + * method is invoked by <code>handleChanges(ISyncInfoSetChangeEvent)</code>. + * Subclasses may override. + * @param event + */ + protected void handleResourceChanges(ISyncInfoTreeChangeEvent event) { + // Refresh the viewer for each changed resource + SyncInfo[] infos = event.getChangedResources(); + for (int i = 0; i < infos.length; i++) { + SyncInfo info = infos[i]; + IResource local = info.getLocal(); + SynchronizeModelElement diffNode = getModelObject(local); + // If a sync info diff node already exists then just update + // it, otherwise remove the old diff node and create a new + // sub-tree. + if (diffNode != null) { + handleChange(diffNode, info); + } + } + } + + /** + * Handle the change for the existing diff node. The diff node + * should be changed to have the given sync info + * @param diffNode the diff node to be changed + * @param info the new sync info for the diff node + */ + protected void handleChange(SynchronizeModelElement diffNode, SyncInfo info) { + IResource local = info.getLocal(); + // TODO: Get any additional sync bits + if(diffNode instanceof SyncInfoModelElement) { + boolean wasConflict = isConflicting(diffNode); + // The update preserves any of the additional sync info bits + ((SyncInfoModelElement)diffNode).update(info); + boolean isConflict = isConflicting(diffNode); + updateLabel(diffNode); + if (wasConflict && !isConflict) { + setParentConflict(diffNode, false); + } else if (!wasConflict && isConflict) { + setParentConflict(diffNode, true); + } + } else { + removeFromViewer(local); + addResources(new IResource[] {local}); + } + // TODO: set any additional sync info bits + } + + protected boolean isConflicting(SynchronizeModelElement diffNode) { + return (diffNode.getKind() & SyncInfo.DIRECTION_MASK) == SyncInfo.CONFLICTING; + } + + /** + * Update the viewer for the sync set removals in the provided event. This + * method is invoked by <code>handleChanges(ISyncInfoSetChangeEvent)</code>. + * Subclasses may override. + * @param event + */ + protected void handleResourceRemovals(ISyncInfoTreeChangeEvent event) { + // Remove the removed subtrees + IResource[] removedRoots = event.getRemovedSubtreeRoots(); + for (int i = 0; i < removedRoots.length; i++) { + removeFromViewer(removedRoots[i]); + } + // We have to look for folders that may no longer be in the set + // (i.e. are in-sync) but still have descendants in the set + IResource[] removedResources = event.getRemovedResources(); + for (int i = 0; i < removedResources.length; i++) { + IResource resource = removedResources[i]; + if (resource.getType() != IResource.FILE) { + SynchronizeModelElement node = getModelObject(resource); + if (node != null) { + removeFromViewer(resource); + addResources(new IResource[] {resource}); + } + } + } + } + + protected void reset() { + try { + refreshViewer = false; + + // Clear existing model, but keep the root node + resourceMap.clear(); + clearModelObjects(getRoot()); + // remove all from tree viewer + IDiffElement[] elements = getRoot().getChildren(); + for (int i = 0; i < elements.length; i++) { + viewer.remove(elements[i]); + } + + // Rebuild the model + associateDiffNode(getRoot()); + buildModelObjects(getRoot()); + + // Notify listeners that model has changed + getRoot().fireChanges(); + } finally { + refreshViewer = true; + } + TeamUIPlugin.getStandardDisplay().asyncExec(new Runnable() { + public void run() { + if (viewer != null && !viewer.getControl().isDisposed()) { + viewer.refresh(); + } + } + }); + } + + protected RootDiffNode getRoot() { + return root; + } + + protected SyncInfoTree getSyncInfoTree() { + return set; + } + + /** + * Remove any traces of the resource and any of it's descendants in the + * hiearchy defined by the content provider from the content provider and + * the viewer it is associated with. + * @param resource + */ + protected void removeFromViewer(IResource resource) { + SynchronizeModelElement node = getModelObject(resource); + if (node == null) return; + if (isConflicting(node)) { + setParentConflict(node, false); + } + clearModelObjects(node); + if (canUpdateViewer()) { + AbstractTreeViewer tree = getTreeViewer(); + tree.remove(node); + } + } + + protected void addToViewer(SynchronizeModelElement node) { + associateDiffNode(node); + node.addPropertyChangeListener(listener); + if (isConflicting(node)) { + setParentConflict(node, true); + } + if (canUpdateViewer()) { + AbstractTreeViewer tree = getTreeViewer(); + tree.add(node.getParent(), node); + } + } + + protected void addResources(IResource[] added) { + for (int i = 0; i < added.length; i++) { + IResource resource = added[i]; + SynchronizeModelElement node = getModelObject(resource); + if (node != null) { + // Somehow the node exists. Remove it and read it to ensure + // what is shown matches the contents of the sync set + removeFromViewer(resource); + } + // Build the sub-tree rooted at this node + SynchronizeModelElement parent = getModelObject(resource.getParent()); + if (parent != null) { + node = createModelObject(parent, resource); + buildModelObjects(node); + } + } + } + + /** + * @param tree + * @return + */ + private boolean canUpdateViewer() { + return refreshViewer && getTreeViewer() != null; + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.ISyncInfoSetChangeListener#syncInfoSetReset(org.eclipse.team.core.subscribers.SyncInfoSet, org.eclipse.core.runtime.IProgressMonitor) + */ + public void syncInfoSetReset(SyncInfoSet set, IProgressMonitor monitor) { + reset(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.ISyncInfoSetChangeListener#syncInfoSetError(org.eclipse.team.core.subscribers.SyncInfoSet, org.eclipse.team.core.ITeamStatus[], org.eclipse.core.runtime.IProgressMonitor) + */ + public void syncInfoSetErrors(SyncInfoSet set, ITeamStatus[] errors, IProgressMonitor monitor) { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.viewers.SynchronizeModelProvider#getInput() + */ + public SynchronizeModelElement getInput() { + return getRoot(); + } + + /** + * Update the label of the given diff node. Diff nodes + * are accumulated and updated in a single call. + * @param diffNode the diff node to be updated + */ + protected void updateLabel(SynchronizeModelElement diffNode) { + pendingLabelUpdates.add(diffNode); + } + + /** + * Forces the viewer to update the labels for parents whose children have + * changed during this round of sync set changes. + */ + protected void firePendingLabelUpdates() { + try { + if (canUpdateViewer()) { + AbstractTreeViewer tree = getTreeViewer(); + tree.update(pendingLabelUpdates.toArray(new Object[pendingLabelUpdates.size()]), null); + } + } finally { + pendingLabelUpdates.clear(); + } + } + + protected void setParentConflict(SynchronizeModelElement diffNode, boolean value) { + diffNode.setPropertyToRoot(SynchronizeModelElement.PROPAGATED_CONFLICT_PROPERTY, value); + updateParentLabels(diffNode); + } + + private void updateParentLabels(SynchronizeModelElement diffNode) { + updateLabel(diffNode); + while (diffNode.getParent() != null) { + diffNode = (SynchronizeModelElement)diffNode.getParent(); + updateLabel(diffNode); + } + } +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/ISyncSetChangedListener.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/ISynchronizeModelChangeListener.java index 8e4737d26..cbe3e8a37 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/sets/ISyncSetChangedListener.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/ISynchronizeModelChangeListener.java @@ -8,15 +8,22 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.team.internal.ui.synchronize.sets; +package org.eclipse.team.ui.synchronize.viewers; + /** - * This interface is used to receive SyncSetChangedEvents from a sync set. + * Listener that gets informed when the <code>DiffNode</code> model created + * by the configurator is created or updated. + * <p> + * Clients may implement this interface. + * </p> + * @since 3.0 */ -public interface ISyncSetChangedListener { - +public interface ISynchronizeModelChangeListener { /** - * The sync set has changed and the event contains the details. + * Called whenever the input model shown in a diff node viewer is updated. + * + * @param input the root <code>DiffNode</code> of the model. */ - public void syncSetChanged(SyncSetChangedEvent event); + public void modelChanged(SynchronizeModelElement root); } diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/StructuredViewerAdvisor.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/StructuredViewerAdvisor.java new file mode 100644 index 000000000..c23fbfaa6 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/StructuredViewerAdvisor.java @@ -0,0 +1,322 @@ +/******************************************************************************* + * 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.ui.synchronize.viewers; + +import org.eclipse.compare.structuremergeviewer.*; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.action.*; +import org.eclipse.jface.util.ListenerList; +import org.eclipse.jface.viewers.*; +import org.eclipse.swt.events.MenuEvent; +import org.eclipse.swt.events.MenuListener; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.core.synchronize.SyncInfoSet; +import org.eclipse.team.internal.core.Assert; +import org.eclipse.team.internal.ui.Utils; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.internal.PluginAction; +import org.eclipse.ui.model.BaseWorkbenchContentProvider; + +/** + * A <code>TreeViewerAdvisor</code> object controls various UI + * aspects of sync info viewers like the context menu, toolbar, content + * provider, and label provider. A configuration is created to display + * {@link SyncInfo} objects contained in the provided {@link SyncInfoSet}. + * <p> + * This configuration allows viewer contributions made in a plug-in manifest to + * be scoped to a particular unique id. As a result the context menu for the + * viewer can be configured to show object contributions for random id schemes. + * To enable declarative action contributions for a configuration there are two + * steps required: + * <ul> + * <li>Create a viewer contribution with a <code>targetID</code> that groups + * sets of actions that are related. A common pratice for synchronize view + * configurations is to use the participant id as the targetID. + * + * <pre> + * <viewerContribution + * id="org.eclipse.team.ccvs.ui.CVSCompareSubscriberContributions" + * targetID="org.eclipse.team.cvs.ui.compare-participant"> + * ... + * </pre> + * + * <li>Create a configuration instance with a <code>menuID</code> that + * matches the targetID in the viewer contribution. + * </ul> + * <p> + * Clients may use this class as is, or subclass to add new state and behavior. + * The default behavior is to show sync info in a tree + * </p> + * @since 3.0 + */ +public abstract class StructuredViewerAdvisor { + + private SyncInfoSet set; + private String menuId; + private StructuredViewer viewer; + private SynchronizeModelProvider diffNodeController; + private ListenerList listeners; + + public StructuredViewerAdvisor(SyncInfoSet set) { + this(null, set); + } + + public StructuredViewerAdvisor(String menuId, SyncInfoSet set) { + this.set = set; + this.menuId = menuId; + } + + /** + * Initialize the viewer with the elements of this configuration, including + * content and label providers, sorter, input and menus. This method is + * invoked from the constructor of <code>SyncInfoDiffTreeViewer</code> to + * initialize the viewers. A configuration instance may only be used with + * one viewer. + + * @param viewer the viewer being initialized + */ + public void initializeViewer(StructuredViewer viewer) { + Assert.isTrue(this.viewer == null, "Can only be initialized once."); //$NON-NLS-1$ + this.viewer = viewer; + + initializeListeners(viewer); + hookContextMenu(viewer); + initializeActions(viewer); + viewer.setLabelProvider(getLabelProvider()); + viewer.setContentProvider(getContentProvider()); + + // The input may of been set already. In that case, don't change it and + // simply assign it to the view. + if(diffNodeController == null) { + diffNodeController = getDiffNodeController(); + diffNodeController.prepareInput(null); + } + setInput(viewer); + } + + public void addInputChangedListener(ISynchronizeModelChangeListener listener) { + if (listeners == null) + listeners= new ListenerList(); + listeners.add(listener); + } + + public void removeInputChangedListener(ISynchronizeModelChangeListener listener) { + if (listeners != null) { + listeners.remove(listener); + if (listeners.isEmpty()) + listeners= null; + } + } + + protected void fireChanges() { + if (listeners != null) { + Object[] l= listeners.getListeners(); + for (int i= 0; i < l.length; i++) + ((ISynchronizeModelChangeListener) l[i]).modelChanged(diffNodeController.getInput()); + } + } + + + /** + * Creates the input for this view and initializes it. At the time this method + * is called the viewer may not of been created yet. + * + * @param monitor shows progress while preparing the input + * @return the input that can be shown in a viewer + */ + public Object prepareInput(IProgressMonitor monitor) throws TeamException { + if(diffNodeController != null) { + diffNodeController.dispose(); + } + diffNodeController = getDiffNodeController(); + return diffNodeController.prepareInput(monitor); + } + + /** + * Get the input that will be assigned to the viewer initialized by this + * configuration. Subclass may override. + * @return the viewer input + */ + protected abstract SynchronizeModelProvider getDiffNodeController(); + + /** + * Get the label provider that will be assigned to the viewer initialized + * by this configuration. Subclass may override but should either wrap the + * default one provided by this method or subclass <code>TeamSubscriberParticipantLabelProvider</code>. + * In the later case, the logical label provider should still be assigned + * to the subclass of <code>TeamSubscriberParticipantLabelProvider</code>. + * @param logicalProvider + * the label provider for the selected logical view + * @return a label provider + * @see SynchronizeModelElementLabelProvider + */ + protected ILabelProvider getLabelProvider() { + return new SynchronizeModelElementLabelProvider(); + } + + protected IStructuredContentProvider getContentProvider() { + return new BaseWorkbenchContentProvider(); + } + + /** + * Method invoked from <code>initializeViewer(Composite, StructuredViewer)</code> + * in order to initialize any listeners for the viewer. + * @param viewer + * the viewer being initialize + */ + protected abstract void initializeListeners(final StructuredViewer viewer); + + /** + * Return the <code>SyncInfoSet</code> being shown by the viewer + * associated with this configuration. + * @return a <code>SyncInfoSet</code> + */ + public SyncInfoSet getSyncInfoSet() { + return set; + } + + /** + * Callback that is invoked when a context menu is about to be shown in the + * diff viewer. + * @param viewer + * the viewer + * @param manager + * the menu manager + */ + protected void fillContextMenu(final StructuredViewer viewer, IMenuManager manager) { + // subclasses will add actions + } + + protected StructuredViewer getViewer() { + return viewer; + } + + /** + * Cleanup listeners + */ + public void dispose() { + if(diffNodeController != null) { + diffNodeController.dispose(); + } + } + + /** + * Return the menu id that is used to obtain context menu items from the + * workbench. + * @return the menuId. + */ + public String getMenuId() { + return menuId; + } + + /** + * Returns whether workbench menu items whould be included in the context + * menu. By default, this returns <code>true</code> if there is a menu id + * and <code>false</code> otherwise + * @return whether to include workbench context menu items + */ + protected boolean allowParticipantMenuContributions() { + return getMenuId() != null; + } + + protected void aSyncExec(Runnable r) { + final Control ctrl = viewer.getControl(); + if (ctrl != null && !ctrl.isDisposed()) { + ctrl.getDisplay().asyncExec(r); + } + } + + /** + * @param viewer + */ + protected void setInput(StructuredViewer viewer) { + diffNodeController.setViewer(viewer); + viewer.setSorter(diffNodeController.getViewerSorter()); + DiffNode input = diffNodeController.getInput(); + input.addCompareInputChangeListener(new ICompareInputChangeListener() { + public void compareInputChanged(ICompareInput source) { + fireChanges(); + } + }); + viewer.setInput(diffNodeController.getInput()); + } + + /** + * Method invoked from <code>initializeViewer(Composite, StructuredViewer)</code> + * in order to initialize any actions for the viewer. It is invoked before + * the input is set on the viewer in order to allow actions to be + * initialized before there is any reaction to the input being set (e.g. + * selecting and opening the first element). + * <p> + * The default behavior is to add the up and down navigation nuttons to the + * toolbar. Subclasses can override. + * @param viewer + * the viewer being initialize + */ + protected void initializeActions(StructuredViewer viewer) { + } + + /** + * Method invoked from <code>initializeViewer(Composite, StructuredViewer)</code> + * in order to configure the viewer to call <code>fillContextMenu(StructuredViewer, IMenuManager)</code> + * when a context menu is being displayed in the diff tree viewer. + * @param viewer + * the viewer being initialized + * @see fillContextMenu(StructuredViewer, IMenuManager) + */ + protected void hookContextMenu(final StructuredViewer viewer) { + final MenuManager menuMgr = new MenuManager(getMenuId()); //$NON-NLS-1$ + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + + public void menuAboutToShow(IMenuManager manager) { + fillContextMenu(viewer, manager); + } + }); + Menu menu = menuMgr.createContextMenu(viewer.getControl()); + menu.addMenuListener(new MenuListener() { + + public void menuHidden(MenuEvent e) { + } + + // Hack to allow action contributions to update their + // state before the menu is shown. This is required when + // the state of the selection changes and the contributions + // need to update enablement based on this. + public void menuShown(MenuEvent e) { + IContributionItem[] items = menuMgr.getItems(); + for (int i = 0; i < items.length; i++) { + IContributionItem item = items[i]; + if (item instanceof ActionContributionItem) { + IAction actionItem = ((ActionContributionItem) item).getAction(); + if (actionItem instanceof PluginAction) { + ((PluginAction) actionItem).selectionChanged(viewer.getSelection()); + } + } + } + } + }); + viewer.getControl().setMenu(menu); + if (allowParticipantMenuContributions()) { + IWorkbenchPartSite site = Utils.findSite(viewer.getControl()); + if (site == null) { + site = Utils.findSite(); + } + if (site != null) { + site.registerContextMenu(getMenuId(), menuMgr, viewer); + } + } + } + + public abstract boolean navigate(boolean next); +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SyncInfoCompareInput.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SyncInfoCompareInput.java new file mode 100644 index 000000000..898aee5cc --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SyncInfoCompareInput.java @@ -0,0 +1,173 @@ +/******************************************************************************* + * 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.ui.synchronize.viewers; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.compare.*; +import org.eclipse.compare.structuremergeviewer.DiffNode; +import org.eclipse.core.runtime.*; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.graphics.Image; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.core.synchronize.SyncInfo; +import org.eclipse.team.internal.core.Assert; +import org.eclipse.team.internal.ui.*; +import org.eclipse.team.internal.ui.synchronize.LocalResourceTypedElement; +import org.eclipse.team.ui.ISharedImages; + +/** + * A {@link SyncInfo} editor input used as input to a two-way or three-way + * compare viewer. It defines methods for accessing the three sides for the + * compare, and a name and image which is used when displaying the three way input + * in an editor. This input can alternatly be used to show compare results in + * a dialog by calling {@link CompareUI#openCompareDialog()}. + * <p> + * Supports saving the local resource that is changed in the editor. + * </p> + * <p> + * Use {@link SynchronizeCompareInput} to display more than one <code>SyncInfo</code> + * in an compare viewer. + * </p> + * @see SyncInfoModelElement + * @since 3.0 + */ +public class SyncInfoCompareInput extends CompareEditorInput { + + private SyncInfoModelElement node; + + public SyncInfoCompareInput(SyncInfo sync) { + super(new CompareConfiguration()); + Assert.isNotNull(sync); + this.node = new SyncInfoModelElement(null, sync); + initializeContentChangeListeners(); + } + + private void initializeContentChangeListeners() { + ITypedElement te = node.getLeft(); + if (te instanceof IContentChangeNotifier) { + ((IContentChangeNotifier) te).addContentChangeListener(new IContentChangeListener() { + public void contentChanged(IContentChangeNotifier source) { + try { + saveChanges(new NullProgressMonitor()); + } catch (CoreException e) { + } + } + }); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.compare.CompareEditorInput#getTitleImage() + */ + public Image getTitleImage() { + ImageRegistry reg = TeamUIPlugin.getPlugin().getImageRegistry(); + Image image = reg.get(ISharedImages.IMG_SYNC_VIEW); + if (image == null) { + image = TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_SYNC_VIEW).createImage(); + reg.put(ISharedImages.IMG_SYNC_VIEW, image); + } + return image; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.compare.CompareEditorInput#prepareInput(org.eclipse.core.runtime.IProgressMonitor) + */ + protected Object prepareInput(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + // update the title now that the remote revision number as been fetched + // from the server + setTitle(getTitle()); + Utils.updateLabels(node.getSyncInfo(), getCompareConfiguration()); + try { + node.cacheContents(monitor); + } catch (TeamException e) { + throw new InvocationTargetException(e); + } + return node; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.compare.CompareEditorInput#getTitle() + */ + public String getTitle() { + return Policy.bind("SyncInfoCompareInput.title", node.getName()); //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IEditorInput#getImageDescriptor() + */ + public ImageDescriptor getImageDescriptor() { + return TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_SYNC_MODE_FREE); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IEditorInput#getToolTipText() + */ + public String getToolTipText() { + return ""; + //return Policy.bind("SyncInfoCompareInput.tooltip", participant.getName(), node.getName()); //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object other) { + if (other == this) + return true; + if (other instanceof SyncInfoCompareInput) { + return getSyncInfo().equals(((SyncInfoCompareInput) other).getSyncInfo()); + } + return false; + } + + /* + * (non-Javadoc) + * + * @see CompareEditorInput#saveChanges(org.eclipse.core.runtime.IProgressMonitor) + */ + public void saveChanges(IProgressMonitor pm) throws CoreException { + super.saveChanges(pm); + if (node != null) { + try { + commit(pm, node); + } finally { + setDirty(false); + } + } + } + + private static void commit(IProgressMonitor pm, DiffNode node) throws CoreException { + ITypedElement left = node.getLeft(); + if (left instanceof LocalResourceTypedElement) + ((LocalResourceTypedElement) left).commit(pm); + + ITypedElement right = node.getRight(); + if (right instanceof LocalResourceTypedElement) + ((LocalResourceTypedElement) right).commit(pm); + } + + public SyncInfo getSyncInfo() { + return node.getSyncInfo(); + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SyncInfoModelElement.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SyncInfoModelElement.java new file mode 100644 index 000000000..5ac2c32b9 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SyncInfoModelElement.java @@ -0,0 +1,234 @@ +/******************************************************************************* + * 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.ui.synchronize.viewers; + +import org.eclipse.compare.ITypedElement; +import org.eclipse.compare.ResourceNode; +import org.eclipse.compare.structuremergeviewer.*; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.internal.ui.Policy; +import org.eclipse.team.internal.ui.synchronize.LocalResourceTypedElement; +import org.eclipse.team.internal.ui.synchronize.RemoteResourceTypedElement; + +/** + * A diff node used to display the synchronization state for resources described by + * existing {@link SyncInfo} objects. The synchronization state for a node can + * change after it has been created. Since it implements the <code>ITypedElement</code> + * and <code>ICompareInput</code> interfaces it can be used directly to + * display the compare result in a <code>DiffTreeViewer</code> and as the + * input to any other compare/merge viewer. + * <p> + * You can access the {@link SyncInfoSet} this node was created from for quick access + * to the underlying sync state model. + * </p> + * <p> + * TODO: mention node builders and syncinfocompareinput and syncinfodifftree viewer + * Clients typically use this class as is, but may subclass if required. + * @see DiffTreeViewer + * @see Differencer + */ +public class SyncInfoModelElement extends SynchronizeModelElement { + + private ITypedElement ancestor; + private SyncInfo info; + + /** + * Construct a <code>SyncInfoModelElement</code> for the given resource. The {@link SyncInfoSet} + * that contains sync states for this resource must also be provided. This set is used + * to access the underlying sync state model that is the basis for this node this helps for + * providing quick access to the logical containment + * + * @param set The set associated with the diff tree veiwer + * @param resource The resource for the node + */ + public SyncInfoModelElement(IDiffContainer parent, SyncInfo info) { + super(parent); + update(info); + } + + public void update(SyncInfo info) { + this.info = info; + // update state + setKind(info.getKind()); + // local + setLeft(createLocalTypeElement(info)); + // remote + setRight(createRemoteTypeElement(info)); + // base + setAncestor(createBaseTypeElement(info)); + } + + /* (non-Javadoc) + * @see org.eclipse.compare.structuremergeviewer.DiffElement#getKind() + */ + public int getKind() { + SyncInfo info = getSyncInfo(); + if (info != null) { + return info.getKind(); + } else { + return SyncInfo.IN_SYNC; + } + } + + /** + * We have to track the base because <code>DiffNode</code> doesn't provide a + * setter. See: + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=52261 + */ + public void setAncestor(ITypedElement ancestor) { + this.ancestor = ancestor; + } + + /* (non-Javadoc) + * @see org.eclipse.compare.structuremergeviewer.DiffNode#getAncestor() + */ + public ITypedElement getAncestor() { + return this.ancestor; + } + + /* (non-Javadoc) + * @see org.eclipse.compare.structuremergeviewer.DiffNode#getName() + */ + public String getName() { + IResource resource = getResource(); + if(resource != null) { + return resource.getName(); + } else { + return super.getName(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + public Object getAdapter(Class adapter) { + if(adapter == SyncInfo.class) { + return getSyncInfo(); + } + return super.getAdapter(adapter); + } + + /** + * Helper method that returns the resource associated with this node. A node is not + * required to have an associated local resource. + * @return the resource associated with this node or <code>null</code> if the local + * contributor is not a resource. + */ + public IResource getResource() { + ITypedElement element = getLeft(); + if(element instanceof ResourceNode) { + return ((ResourceNode)element).getResource(); + } + return null; + } + + /** + * Return true if the receiver's Subscriber and Resource are equal to that of object. + * @param object The object to test + * @return true has the same subsriber and resource + */ + public boolean equals(Object object) { + return this==object; + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + IResource resource = getResource(); + if (resource == null) { + return super.hashCode(); + } + return resource.hashCode(); + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + return getResource() != null ? getResource().getFullPath().toString() : getName(); + } + + /** + * Cache the contents for the base and remote. + * @param monitor + */ + public void cacheContents(IProgressMonitor monitor) throws TeamException { + ITypedElement base = getAncestor(); + ITypedElement remote = getRight(); + int work = Math.min((remote== null ? 0 : 50) + (base == null ? 0 : 50), 10); + monitor.beginTask(null, work); + try { + if (base != null && base instanceof RemoteResourceTypedElement) { + ((RemoteResourceTypedElement)base).cacheContents(Policy.subMonitorFor(monitor, 50)); + } + if (remote != null && remote instanceof RemoteResourceTypedElement) { + ((RemoteResourceTypedElement)remote).cacheContents(Policy.subMonitorFor(monitor, 50)); + } + } finally { + monitor.done(); + } + } + + public SyncInfo getSyncInfo() { + return info; + } + + /** + * Create an ITypedElement for the given local resource. The returned ITypedElement + * will prevent editing of outgoing deletions. + */ + private static ITypedElement createTypeElement(final IResource resource, final int kind) { + if(resource != null) { + return new LocalResourceTypedElement(resource) { + public boolean isEditable() { + if(! resource.exists() && SyncInfo.getDirection(kind) == SyncInfo.OUTGOING && SyncInfo.getChange(kind) == SyncInfo.DELETION) { + return false; + } + return super.isEditable(); + } + }; + } + return null; + } + + /** + * Create an ITypedElement for the given remote resource. The contents for the remote resource + * will be retrieved from the given IStorage which is a local cache used to buffer the remote contents + */ + private static ITypedElement createTypeElement(IResourceVariant remoteResource) { + return new RemoteResourceTypedElement(remoteResource); + } + + private static ITypedElement createRemoteTypeElement(SyncInfo info) { + if(info != null && info.getRemote() != null) { + return createTypeElement(info.getRemote()); + } + return null; + } + + private static ITypedElement createLocalTypeElement(SyncInfo info) { + if(info != null && info.getLocal() != null) { + return createTypeElement(info.getLocal(), info.getKind()); + } + return null; + } + + private static ITypedElement createBaseTypeElement(SyncInfo info) { + if(info != null && info.getBase() != null) { + return createTypeElement(info.getBase()); + } + return null; + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SynchronizeCompareInput.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SynchronizeCompareInput.java new file mode 100644 index 000000000..2a3edd30e --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SynchronizeCompareInput.java @@ -0,0 +1,196 @@ +/******************************************************************************* + * 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.ui.synchronize.viewers; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.compare.*; +import org.eclipse.compare.internal.INavigatable; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.viewers.*; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.internal.ui.Utils; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.progress.IProgressService; + +/** + * A <code>CompareEditorInput</code> whose diff viewer shows the resources contained + * in a <code>SyncInfoSet</code>. The configuration of the diff viewer is determined by the + * <code>SyncInfoSetCompareConfiguration</code> that is used to create the + * <code>SynchronizeCompareInput</code>. + * + * uses the presentation model defined by the configuration. + * + * @since 3.0 + */ +public class SynchronizeCompareInput extends CompareEditorInput { + + private TreeViewerAdvisor diffViewerConfiguration; + private Viewer diffViewer; + private NavigationAction nextAction; + private NavigationAction previousAction; + + /** + * Create a <code>SynchronizeCompareInput</code> whose diff viewer is configured + * using the provided <code>SyncInfoSetCompareConfiguration</code>. + * @param configuration the compare configuration + * @param diffViewerConfiguration the diff viewer configuration + */ + public SynchronizeCompareInput(CompareConfiguration configuration, TreeViewerAdvisor diffViewerConfiguration) { + super(configuration); + this.diffViewerConfiguration = diffViewerConfiguration; + } + + public final Viewer createDiffViewer(Composite parent) { + this.diffViewer = internalCreateDiffViewer(parent, getViewerConfiguration()); + diffViewer.getControl().setData(CompareUI.COMPARE_VIEWER_TITLE, getTitle()); + + /* + * This viewer can participate in navigation support in compare editor inputs. Note that + * it is currently accessing an internal compare interface that should be made public. See + * the following bug report https://bugs.eclipse.org/bugs/show_bug.cgi?id=48795. + */ + INavigatable nav= new INavigatable() { + public boolean gotoDifference(boolean next) { + return diffViewerConfiguration.navigate(next); + } + }; + diffViewer.getControl().setData(INavigatable.NAVIGATOR_PROPERTY, nav); + + nextAction = new NavigationAction(true); + previousAction = new NavigationAction(false); + nextAction.setCompareEditorInput(this); + previousAction.setCompareEditorInput(this); + + + initializeToolBar(diffViewer.getControl().getParent()); + initializeDiffViewer(diffViewer); + return diffViewer; + } + + /** + * Create the diff viewer for this compare input. This method simply creates the widget. + * Any initialization is performed in the <code>initializeDiffViewer(StructuredViewer)</code> + * method. The default diff viewer is a <code>SyncInfoDiffTreeViewer</code>. Subclass may override. + * @param parent the parent <code>Composite</code> of the diff viewer to be created + * @param diffViewerConfiguration the configuration for the diff viewer + * @return the created diff viewer + */ + protected StructuredViewer internalCreateDiffViewer(Composite parent, TreeViewerAdvisor diffViewerConfiguration) { + TreeViewer viewer = new TreeViewerAdvisor.NavigableTreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + GridData data = new GridData(GridData.FILL_BOTH); + viewer.getControl().setLayoutData(data); + diffViewerConfiguration.initializeViewer(viewer); + return viewer; + } + + protected TreeViewerAdvisor getViewerConfiguration() { + return diffViewerConfiguration; + } + + protected Viewer getViewer() { + return diffViewer; + } + + /** + * Initialize the diff viewer created for this compare input. If a subclass + * overrides the <code>createDiffViewer(Composite)</code> method, it should + * invoke this method on the created viewer in order to get the proper + * labelling in the compare input's contents viewers. + * @param viewer the diff viewer created by the compare input + */ + protected void initializeDiffViewer(Viewer viewer) { + if (viewer instanceof StructuredViewer) { + ((StructuredViewer) viewer).addOpenListener(new IOpenListener() { + public void open(OpenEvent event) { + ISelection s = event.getSelection(); + final SyncInfoModelElement node = getElement(s); + if (node != null) { + IResource resource = node.getResource(); + int kind = node.getKind(); + if (resource != null && resource.getType() == IResource.FILE) { + // Cache the contents because compare doesn't show progress + // when calling getContents on a diff node. + IProgressService manager = PlatformUI.getWorkbench().getProgressService(); + try { + manager.busyCursorWhile(new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + try { + node.cacheContents(monitor); + } catch (TeamException e) { + throw new InvocationTargetException(e); + } + } + }); + } catch (InvocationTargetException e) { + Utils.handle(e); + } catch (InterruptedException e) { + Utils.handle(e); + } finally { + // Update the labels even if the content wasn't fetched correctly. This is + // required because the selection would still of changed. + Utils.updateLabels(node.getSyncInfo(), getCompareConfiguration()); + } + } + } + } + }); + } + } + + public void contributeToToolBar(ToolBarManager tbm) { + if(nextAction != null && previousAction != null) { + tbm.appendToGroup("navigation", nextAction); //$NON-NLS-1$ + tbm.appendToGroup("navigation", previousAction); //$NON-NLS-1$ + } + } + + private void initializeToolBar(Composite parent) { + ToolBarManager tbm= CompareViewerPane.getToolBarManager(parent); + if (tbm != null) { + tbm.removeAll(); + tbm.add(new Separator("navigation")); //$NON-NLS-1$ + contributeToToolBar(tbm); + tbm.update(true); + } + } + + /* private */ SyncInfoModelElement getElement(ISelection selection) { + if (selection != null && selection instanceof IStructuredSelection) { + IStructuredSelection ss= (IStructuredSelection) selection; + if (ss.size() == 1) { + Object o = ss.getFirstElement(); + if(o instanceof SyncInfoModelElement) { + return (SyncInfoModelElement)o; + } + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.compare.CompareEditorInput#prepareInput(org.eclipse.core.runtime.IProgressMonitor) + */ + protected Object prepareInput(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + try { + return getViewerConfiguration().prepareInput(monitor); + } catch (TeamException e) { + throw new InvocationTargetException(e); + } + } +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SynchronizeModelElement.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SynchronizeModelElement.java new file mode 100644 index 000000000..62921579a --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SynchronizeModelElement.java @@ -0,0 +1,186 @@ +/******************************************************************************* + * 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.ui.synchronize.viewers; + +import org.eclipse.compare.structuremergeviewer.*; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.*; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.util.*; +import org.eclipse.team.core.synchronize.SyncInfo; +import org.eclipse.team.internal.ui.TeamUIPlugin; +import org.eclipse.ui.model.IWorkbenchAdapter; + +/** + * A node that represents synchronization state between elements. + * @since 3.0 + */ +public abstract class SynchronizeModelElement extends DiffNode implements IAdaptable { + + public static final String BUSY_PROPERTY = TeamUIPlugin.ID + ".busy"; //$NON-NLS-1$ + public static final String PROPAGATED_CONFLICT_PROPERTY = TeamUIPlugin.ID + ".conflict"; //$NON-NLS-1$ + + /* + * Internal flags bits for stroing properties in the flags variable + */ + private static final int BUSY_FLAG = 1; + private static final int PROPAGATED_CONFLICT_FLAG = 2; + + // Instance variable containing the flags for this node + private int flags; + private ListenerList listeners; + + public SynchronizeModelElement(IDiffContainer parent) { + super(parent, SyncInfo.IN_SYNC); + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + public Object getAdapter(Class adapter) { + return Platform.getAdapterManager().getAdapter(this, adapter); + } + + public synchronized void addPropertyChangeListener(IPropertyChangeListener listener) { + if (listeners == null) { + listeners = new ListenerList(); + } + listeners.add(listener); + } + + public synchronized void removePropertyChangeListener(IPropertyChangeListener listener) { + if (listeners != null) { + listeners.remove(listener); + if (listeners.isEmpty()) { + listeners = null; + } + } + } + + /** + * Return whether this node has the given property set. + * @param propertyName the flag to test + * @return <code>true</code> if the property is set + */ + public boolean getProperty(String propertyName) { + return (getFlags() & getFlag(propertyName)) > 0; + } + + /** + * Add the flag to the flags for this node + * @param propertyName the flag to add + */ + public void setProperty(String propertyName, boolean value) { + if (value) { + if (!getProperty(propertyName)) { + int flag = getFlag(propertyName); + flags |= flag; + firePropertyChange(propertyName); + } + } else { + if (getProperty(propertyName)) { + int flag = getFlag(propertyName); + flags ^= flag; + firePropertyChange(propertyName); + } + } + } + + public void setPropertyToRoot(String propertyName, boolean value) { + if (value) { + addToRoot(propertyName); + } else { + removeToRoot(propertyName); + } + } + + + public ImageDescriptor getImageDescriptor(Object object) { + IResource resource = getResource(); + if(resource != null) { + IWorkbenchAdapter adapter = (IWorkbenchAdapter)((IAdaptable) resource).getAdapter(IWorkbenchAdapter.class); + return adapter.getImageDescriptor(resource); + } + return null; + } + + public abstract IResource getResource(); + + private void addToRoot(String flag) { + setProperty(flag, true); + SynchronizeModelElement parent = (SynchronizeModelElement)getParent(); + if (parent != null) { + if (parent.getProperty(flag)) return; + parent.addToRoot(flag); + } + } + + private void firePropertyChange(String propertyName) { + Object[] allListeners; + synchronized(this) { + if (listeners == null) return; + allListeners = listeners.getListeners(); + } + boolean set = getProperty(propertyName); + final PropertyChangeEvent event = new PropertyChangeEvent(this, propertyName, Boolean.valueOf(!set), Boolean.valueOf(set)); + for (int i = 0; i < allListeners.length; i++) { + Object object = allListeners[i]; + if (object instanceof IPropertyChangeListener) { + final IPropertyChangeListener listener = (IPropertyChangeListener)object; + Platform.run(new ISafeRunnable() { + public void handleException(Throwable exception) { + // Exceptions logged by the platform + } + public void run() throws Exception { + listener.propertyChange(event); + } + }); + } + } + } + + private int getFlag(String propertyName) { + if (propertyName == BUSY_PROPERTY) { + return BUSY_FLAG; + } else if (propertyName == PROPAGATED_CONFLICT_PROPERTY) { + return PROPAGATED_CONFLICT_FLAG; + } + return 0; + } + + private int getFlags() { + return flags; + } + + private boolean hasChildWithFlag(String flag) { + IDiffElement[] childen = getChildren(); + for (int i = 0; i < childen.length; i++) { + IDiffElement element = childen[i]; + if (((SynchronizeModelElement)element).getProperty(flag)) { + return true; + } + } + return false; + } + + private void removeToRoot(String flag) { + setProperty(flag, false); + SynchronizeModelElement parent = (SynchronizeModelElement)getParent(); + if (parent != null) { + // If the parent doesn't have the tag, no recalculation is required + // Also, if the parent still has a child with the tag, no recalculation is needed + if (parent.getProperty(flag) && !parent.hasChildWithFlag(flag)) { + // The parent no longer has the flag so propogate the reclaculation + parent.removeToRoot(flag); + } + } + } +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SynchronizeModelElementLabelProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SynchronizeModelElementLabelProvider.java new file mode 100644 index 000000000..094edbd44 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SynchronizeModelElementLabelProvider.java @@ -0,0 +1,204 @@ +/******************************************************************************* + * 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.ui.synchronize.viewers; + +import java.util.*; + +import org.eclipse.compare.CompareConfiguration; +import org.eclipse.compare.structuremergeviewer.DiffNode; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.*; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.*; +import org.eclipse.team.core.synchronize.SyncInfo; +import org.eclipse.team.internal.ui.*; +import org.eclipse.team.ui.ISharedImages; +import org.eclipse.ui.internal.WorkbenchColors; +import org.eclipse.ui.model.WorkbenchLabelProvider; + +/** + * @since 3.0 + */ +public class SynchronizeModelElementLabelProvider extends LabelProvider implements IColorProvider { + + // Cache for folder images that have been overlayed with conflict icon + private Map fgImageCache; + + // Contains direction images + CompareConfiguration compareConfig = new CompareConfiguration(); + + // Used as the base label provider for retreiving image and text from + // the workbench adapter. + private WorkbenchLabelProvider workbenchLabelProvider = new WorkbenchLabelProvider(); + + /** + * Decorating label provider that also support color providers + */ + public static class DecoratingColorLabelProvider extends DecoratingLabelProvider implements IColorProvider { + + public DecoratingColorLabelProvider(ILabelProvider provider, ILabelDecorator decorator) { + super(provider, decorator); + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.viewers.IColorProvider#getForeground(java.lang.Object) + */ + public Color getForeground(Object element) { + ILabelProvider p = getLabelProvider(); + if (p instanceof IColorProvider) { + return ((IColorProvider) p).getForeground(element); + } + return null; + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.viewers.IColorProvider#getBackground(java.lang.Object) + */ + public Color getBackground(Object element) { + ILabelProvider p = getLabelProvider(); + if (p instanceof IColorProvider) { + return ((IColorProvider) p).getBackground(element); + } + return null; + } + } + + public SynchronizeModelElementLabelProvider() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.viewers.IColorProvider#getForeground(java.lang.Object) + */ + public Color getForeground(Object element) { + if (element instanceof SynchronizeModelElement) { + SynchronizeModelElement node = (SynchronizeModelElement)element; + if(node.getProperty(SynchronizeModelElement.BUSY_PROPERTY)) { + return WorkbenchColors.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); + } + } + return null; + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.viewers.IColorProvider#getBackground(java.lang.Object) + */ + public Color getBackground(Object element) { + return null; + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object) + */ + public Image getImage(Object element) { + Image base = workbenchLabelProvider.getImage(element); + if (base != null) { + if (element instanceof DiffNode) { + DiffNode syncNode = (DiffNode) element; + int kind = syncNode.getKind(); + Image decoratedImage; + decoratedImage = getCompareImage(base, kind); + if (syncNode.hasChildren()) { + // The reason we still overlay the compare image is to + // ensure that the image width for all images shown in the viewer + // are consistent. + return propagateConflicts(decoratedImage, syncNode); + } else { + return decoratedImage; + } + } + } + return base; + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) + */ + public String getText(Object element) { + String base = workbenchLabelProvider.getText(element); + if (element instanceof DiffNode) { + if (TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_SYNCINFO_IN_LABEL)) { + // if the folder is already conflicting then don't bother + // propagating the conflict + int kind = ((DiffNode) element).getKind(); + if (kind != SyncInfo.IN_SYNC) { + String syncKindString = SyncInfo.kindToString(kind); + return Policy.bind("TeamSubscriberSyncPage.labelWithSyncKind", base, syncKindString); //$NON-NLS-1$ + } + } + } + return base; + } + + protected Image getCompareImage(Image base, int kind) { + switch (kind & SyncInfo.DIRECTION_MASK) { + case SyncInfo.OUTGOING : + kind = (kind & ~SyncInfo.OUTGOING) | SyncInfo.INCOMING; + break; + case SyncInfo.INCOMING : + kind = (kind & ~SyncInfo.INCOMING) | SyncInfo.OUTGOING; + break; + } + return compareConfig.getImage(base, kind); + } + + private Image propagateConflicts(Image base, DiffNode element) { + // if the folder is already conflicting then don't bother propagating + // the conflict + int kind = element.getKind(); + if ((kind & SyncInfo.DIRECTION_MASK) != SyncInfo.CONFLICTING) { + if (hasDecendantConflicts(element)) { + ImageDescriptor overlay = new OverlayIcon(base, new ImageDescriptor[]{TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_CONFLICT_OVR)}, new int[]{OverlayIcon.BOTTOM_LEFT}, new Point(base.getBounds().width, base.getBounds().height)); + if (fgImageCache == null) { + fgImageCache = new HashMap(10); + } + Image conflictDecoratedImage = (Image) fgImageCache.get(overlay); + if (conflictDecoratedImage == null) { + conflictDecoratedImage = overlay.createImage(); + fgImageCache.put(overlay, conflictDecoratedImage); + } + return conflictDecoratedImage; + } + } + return base; + } + + /** + * Return whether this diff node has descendant conflicts in the view in which it appears. + * @return whether the node has descendant conflicts + */ + private boolean hasDecendantConflicts(DiffNode node) { + if(node instanceof SynchronizeModelElement) { + return ((SynchronizeModelElement)node).getProperty(SynchronizeModelElement.PROPAGATED_CONFLICT_PROPERTY); + } + return false; + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose() + */ + public void dispose() { + compareConfig.dispose(); + if (fgImageCache != null) { + Iterator it = fgImageCache.values().iterator(); + while (it.hasNext()) { + Image element = (Image) it.next(); + element.dispose(); + } + } + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SynchronizeModelElementSorter.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SynchronizeModelElementSorter.java new file mode 100644 index 000000000..7056320c6 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SynchronizeModelElementSorter.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * 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.ui.synchronize.viewers; + +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.team.internal.ui.Utils; +import org.eclipse.ui.views.navigator.ResourceSorter; + +/** + * This class sorts <code>SyncInfoModelElement</code> instances. + * It is not thread safe so it should not be reused between views. + */ +public class SynchronizeModelElementSorter extends ResourceSorter { + + public SynchronizeModelElementSorter() { + super(ResourceSorter.NAME); + } + + /* (non-Javadoc) + * Method declared on ViewerSorter. + */ + public int compare(Viewer viewer, Object o1, Object o2) { + IResource resource1 = getResource(o1); + IResource resource2 = getResource(o2); + int result; + if (resource1 != null && resource2 != null) { + result = super.compare(viewer, resource1, resource2); + } else { + result = super.compare(viewer, o1, o2); + } + return result; + } + + protected IResource getResource(Object obj) { + IResource[] resources = Utils.getResources(new Object[] {obj}); + return resources.length == 1 ? resources[0] : null; + } +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SynchronizeModelProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SynchronizeModelProvider.java new file mode 100644 index 000000000..dbda6b191 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/SynchronizeModelProvider.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.ui.synchronize.viewers; + +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.jface.viewers.ViewerSorter; + +/** + * This class is reponsible for creating and maintaining model of + * DiffNodes that can be shown in a viewer. + * + * @since 3.0 + */ +public abstract class SynchronizeModelProvider { + + protected class RootDiffNode extends UnchangedResourceModelElement { + public RootDiffNode() { + super(null, ResourcesPlugin.getWorkspace().getRoot()); + } + public void fireChanges() { + fireChange(); + } + public boolean hasChildren() { + // This is required to allow the sync framework to be used in wizards + // where the input is not populated until after the compare input is + // created + // (i.e. the compare input will only create the diff viewer if the + // input has children + return true; + } + } + + /** + * Called to initialize this controller and returns the input created by this controller. + * @param monitor + * @return + */ + public abstract SynchronizeModelElement prepareInput(IProgressMonitor monitor); + + /** + * Returns the input created by this controller or <code>null</code> if + * {@link #prepareInput(IProgressMonitor)} hasn't been called on this object yet. + * @return + */ + public abstract SynchronizeModelElement getInput(); + + public abstract void setViewer(StructuredViewer viewer); + + public abstract ViewerSorter getViewerSorter(); + + public abstract void dispose(); +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/TreeViewerAdvisor.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/TreeViewerAdvisor.java new file mode 100644 index 000000000..69875730e --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/TreeViewerAdvisor.java @@ -0,0 +1,345 @@ +/******************************************************************************* + * 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.ui.synchronize.viewers; + +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.*; +import org.eclipse.swt.widgets.*; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.internal.core.Assert; +import org.eclipse.team.internal.ui.*; +import org.eclipse.team.internal.ui.synchronize.actions.ExpandAllAction; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.internal.dialogs.ContainerCheckedTreeViewer; + +/** + * A <code>TreeViewerAdvisor</code> object controls various UI + * aspects of sync info viewers like the context menu, toolbar, content + * provider, and label provider. A configuration is created to display + * {@link SyncInfo} objects contained in the provided {@link SyncInfoSet}. + * <p> + * This configuration allows viewer contributions made in a plug-in manifest to + * be scoped to a particular unique id. As a result the context menu for the + * viewer can be configured to show object contributions for random id schemes. + * To enable declarative action contributions for a configuration there are two + * steps required: + * <ul> + * <li>Create a viewer contribution with a <code>targetID</code> that groups + * sets of actions that are related. A common pratice for synchronize view + * configurations is to use the participant id as the targetID. + * + * <pre> + * <viewerContribution + * id="org.eclipse.team.ccvs.ui.CVSCompareSubscriberContributions" + * targetID="org.eclipse.team.cvs.ui.compare-participant"> + * ... + * </pre> + * + * <li>Create a configuration instance with a <code>menuID</code> that + * matches the targetID in the viewer contribution. + * </ul> + * <p> + * Clients may use this class as is, or subclass to add new state and behavior. + * The default behavior is to show sync info in a tree + * </p> + * @since 3.0 + */ +public class TreeViewerAdvisor extends StructuredViewerAdvisor implements IPropertyChangeListener { + + private ExpandAllAction expandAllAction; + + public interface ITreeViewerAccessor { + public void openSelection(); + + public void createChildren(TreeItem item); + } + + public static class NavigableTreeViewer extends TreeViewer implements ITreeViewerAccessor { + public NavigableTreeViewer(Composite parent, int style) { + super(parent, style); + } + + public void openSelection() { + fireOpen(new OpenEvent(this, getSelection())); + } + + public void createChildren(TreeItem item) { + super.createChildren(item); + } + } + + public static class NavigableCheckboxTreeViewer extends ContainerCheckedTreeViewer implements ITreeViewerAccessor { + public NavigableCheckboxTreeViewer(Composite parent, int style) { + super(parent, style); + } + + public void openSelection() { + fireOpen(new OpenEvent(this, getSelection())); + } + + public void createChildren(TreeItem item) { + super.createChildren(item); + } + } + + /** + * Create a <code>SyncInfoSetCompareConfiguration</code> for the given + * sync set. + * @param set + * the <code>SyncInfoSet</code> to be displayed in the + * resulting diff viewer. + */ + public TreeViewerAdvisor(SyncInfoTree set) { + this(null, set); + } + + /** + * Create a <code>SyncInfoSetCompareConfiguration</code> for the given + * sync set and menuId. If the menuId is <code>null</code>, then no + * contributed menus will be shown in the diff viewer created from this + * configuration. + * @param menuId + * the id of <code>targetID</code> specified in <code>viewerContribution</code> + * extension points. + * @param set + * the <code>SyncInfoSet</code> to be displayed in the + * resulting diff viewer + */ + public TreeViewerAdvisor(String menuId, SyncInfoTree set) { + super(menuId, set); + TeamUIPlugin.getPlugin().getPreferenceStore().addPropertyChangeListener(this); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.viewers.StructuredViewerAdvisor#initializeViewer(org.eclipse.jface.viewers.StructuredViewer) + */ + public void initializeViewer(StructuredViewer viewer) { + super.initializeViewer(viewer); + Assert.isTrue(viewer instanceof AbstractTreeViewer); + } + + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.viewers.StructuredViewerAdvisor#initializeListeners(org.eclipse.jface.viewers.StructuredViewer) + */ + protected void initializeListeners(StructuredViewer viewer) { + viewer.addDoubleClickListener(new IDoubleClickListener() { + public void doubleClick(DoubleClickEvent event) { + handleDoubleClick(getViewer(), event); + } + }); + } + + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.viewers.StructuredViewerAdvisor#initializeActions(org.eclipse.jface.viewers.StructuredViewer) + */ + protected void initializeActions(StructuredViewer viewer) { + super.initializeActions(viewer); + expandAllAction = new ExpandAllAction((AbstractTreeViewer) viewer); + Utils.initAction(expandAllAction, "action.expandAll."); //$NON-NLS-1$ + } + + /** + * Handles a double-click event from the viewer. Expands or collapses a + * folder when double-clicked. + * @param viewer + * the viewer + * @param event + * the double-click event + */ + protected void handleDoubleClick(StructuredViewer viewer, DoubleClickEvent event) { + IStructuredSelection selection = (IStructuredSelection) event.getSelection(); + Object element = selection.getFirstElement(); + AbstractTreeViewer treeViewer = (AbstractTreeViewer) getViewer(); + if (treeViewer.getExpandedState(element)) { + treeViewer.collapseToLevel(element, AbstractTreeViewer.ALL_LEVELS); + } else { + TreeViewerAdvisor.navigate((TreeViewer)getViewer(), true /* next */, false /* no-open */, true /* only-expand */); + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.viewers.StructuredViewerAdvisor#getDiffNodeController() + */ + protected SynchronizeModelProvider getDiffNodeController() { + if(getShowCompressedFolders()) { + return new CompressedFoldersModelProvider((SyncInfoTree)getSyncInfoSet()); + } + return new HierarchicalModelProvider((SyncInfoTree)getSyncInfoSet()); + } + + private boolean getShowCompressedFolders() { + return TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_COMPRESS_FOLDERS); + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) + */ + public void propertyChange(PropertyChangeEvent event) { + if (getViewer() != null && event.getProperty().equals(IPreferenceIds.SYNCVIEW_COMPRESS_FOLDERS)) { + try { + prepareInput(null); + setInput(getViewer()); + } catch (TeamException e) { + TeamUIPlugin.log(e); + } + } + } + + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.viewers.StructuredViewerAdvisor#fillContextMenu(org.eclipse.jface.viewers.StructuredViewer, org.eclipse.jface.action.IMenuManager) + */ + protected void fillContextMenu(StructuredViewer viewer, IMenuManager manager) { + manager.add(expandAllAction); + manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.viewers.StructuredViewerAdvisor#navigate(boolean) + */ + public boolean navigate(boolean next) { + return TreeViewerAdvisor.navigate((TreeViewer)getViewer(), next, true, false); + } + /** + * Selects the next (or previous) node of the current selection. + * If there is no current selection the first (last) node in the tree is selected. + * Wraps around at end or beginning. + * Clients may override. + * + * @param next if <code>true</code> the next node is selected, otherwise the previous node + * @return <code>true</code> if at end (or beginning) + */ + public static boolean navigate(TreeViewer viewer, boolean next, boolean fireOpen, boolean expandOnly) { + Tree tree = viewer.getTree(); + if (tree == null) + return false; + TreeItem item = null; + TreeItem children[] = tree.getSelection(); + if (children != null && children.length > 0) + item = children[0]; + if (item == null) { + children = tree.getItems(); + if (children != null && children.length > 0) { + item = children[0]; + if (item != null && item.getItemCount() <= 0) { + setSelection(viewer, item, fireOpen, expandOnly); // Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=20106 + return false; + } + } + } + while (true) { + item = findNextPrev(viewer, item, next); + if (item == null) + break; + if (item.getItemCount() <= 0) + break; + } + if (item != null) { + setSelection(viewer, item, fireOpen, expandOnly); // Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=20106 + return false; + } + return true; + } + + private static void setSelection(TreeViewer viewer, TreeItem ti, boolean fireOpen, boolean expandOnly) { + if (ti != null) { + Object data= ti.getData(); + if (data != null) { + // Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=20106 + ISelection selection = new StructuredSelection(data); + if (expandOnly) { + viewer.expandToLevel(data, 0); + } else { + viewer.setSelection(selection, true); + ISelection currentSelection = viewer.getSelection(); + if (fireOpen && currentSelection != null && selection.equals(currentSelection)) { + if (viewer instanceof ITreeViewerAccessor) { + ((ITreeViewerAccessor) viewer).openSelection(); + } + } + } + } + } + } + + private static TreeItem findNextPrev(TreeViewer viewer, TreeItem item, boolean next) { + if (item == null || !(viewer instanceof ITreeViewerAccessor)) + return null; + TreeItem children[] = null; + ITreeViewerAccessor treeAccessor = (ITreeViewerAccessor) viewer; + if (!next) { + TreeItem parent = item.getParentItem(); + if (parent != null) + children = parent.getItems(); + else + children = item.getParent().getItems(); + if (children != null && children.length > 0) { + // goto previous child + int index = 0; + for (; index < children.length; index++) + if (children[index] == item) + break; + if (index > 0) { + item = children[index - 1]; + while (true) { + treeAccessor.createChildren(item); + int n = item.getItemCount(); + if (n <= 0) + break; + item.setExpanded(true); + item = item.getItems()[n - 1]; + } + // previous + return item; + } + } + // go up + return parent; + } else { + item.setExpanded(true); + treeAccessor.createChildren(item); + if (item.getItemCount() > 0) { + // has children: go down + children = item.getItems(); + return children[0]; + } + while (item != null) { + children = null; + TreeItem parent = item.getParentItem(); + if (parent != null) + children = parent.getItems(); + else + children = item.getParent().getItems(); + if (children != null && children.length > 0) { + // goto next child + int index = 0; + for (; index < children.length; index++) + if (children[index] == item) + break; + if (index < children.length - 1) { + // next + return children[index + 1]; + } + } + // go up + item = parent; + } + } + return item; + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/UnchangedResourceModelElement.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/UnchangedResourceModelElement.java new file mode 100644 index 000000000..a2b17e0d5 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/UnchangedResourceModelElement.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * 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.ui.synchronize.viewers; + +import org.eclipse.compare.structuremergeviewer.IDiffContainer; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IAdaptable; + +/** + * DiffNode that represents a resource that is in sync. + */ +public class UnchangedResourceModelElement extends SynchronizeModelElement implements IAdaptable { + + private IResource resource; + + public UnchangedResourceModelElement(IDiffContainer parent, IResource resource) { + super(parent); + this.resource = resource; + } + + /** + * @return Returns the resource. + */ + public IResource getResource() { + return resource; + } + + /* (non-Javadoc) + * @see org.eclipse.compare.structuremergeviewer.DiffNode#getName() + */ + public String getName() { + return resource.getName(); + } +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/package.html b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/package.html new file mode 100644 index 000000000..6890ad44e --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/viewers/package.html @@ -0,0 +1,82 @@ +<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" + content="text/html; charset=iso-8859-1"> + <meta name="Author" content="IBM"> + <title>Package-level Javadoc</title> +</head> +<body> +<p> +Application programming interfaces for displaying synchronization +states and variants.</p> +<h2>Package Specification</h2> +<p>This package contains classes that support displaying +synchronization information described by SyncInfo. If you consider the +synchronization model described by the classes in +org.eclipse.team.core.synchronize as the physical representation of +resource variants then the classes in this package allow you to control +how the model is presented to the user. One key feature of these APIs +is that they support managing dynamic models.<br> +</p> +<p>There is no specific support for the Synchronize View in this +package. Instead, the classes here can be used to build a page that can +be shown in the view, but they can also be used to show synchronization +information in dialogs, wizards, and editors.<br> +</p> +<p>The central abstractions for presenting synchronization state are:<br> +</p> +<p>- SynchronizeModelProvider, SynchronizeModelElement: are the +building blocks for +describing the logical structure of a synchronization model.<br> +- StructuredViewerAdvisor: are used to +display the logical structure to the user and define the basics such as +the SynchronizeModelProvider, label provider, and context menus.<br> +- SyncInfoCompareInput: is used to show a comparison between a local +resource and a variant in a compare editor.<br> +- SyncInfoSetCompareInput: is used to showing a set of variants in a +compare editor<br> +</p> +<p>Default implementations are provided and there are many levels of +customizations available.<br> +</p> +<h2>Basic Example</h2> +If you have a synchronization model described in a SyncInfoTree and +would like to show it to the user in a simple resource hierarchical +tree viewers you would:<br> +<br> +SyncInfoTree syncTree = getSyncTree();<br> +DiffTreeViewerConfiguration viewerConfiguration = new +DiffTreeViewerConfiguration(syncTree);<br> +TreeViewer viewer = new TreeViewer(parent);<br> +viewerConfiguration.initializeViewer(viewer);<br> +...<br> +viewerConfiguration.dispose();<br> +<br> +Some items of interest in the above example: (1) the viewer +configuration is used to add behavior to different types of tree +viewers and by default will build a hierarchical logical model of the +synchronization info and, (2) the default label provider will show the +nodes with resource decorations plus the standard diff change markers, +(3) the default context menu action is expand all plus any object +contributions.<br> +<br> +Another example, you would like to add additional label decorations, +and actions defined as viewerContribution in your plugin.xml.<br> +<br> +SyncInfoTree syncTree = getSyncTree();<br> +DiffTreeViewerConfiguration viewerConfiguration = new +DiffTreeViewerConfiguration("org.eclipse.team.example.actions", +syncTree) {<br> + protected ILabelProvider getLabelProvider() {<br> + return new +SyncInfoLabelProvider.DecoratingColorLabelProvider(new +SyncInfoLabelProvider(), new MyCustorDecorator());<br> + }<br> +}<br> +TreeViewer viewer = new TreeViewer(parent);<br> +viewerConfiguration.initializeViewer(viewer);<br> +...<br> +viewerConfiguration.dispose();<br> +</body> +</html> diff --git a/examples/org.eclipse.team.examples.filesystem/plugin.xml b/examples/org.eclipse.team.examples.filesystem/plugin.xml index ce1bb0e2d..bda3da5f8 100644 --- a/examples/org.eclipse.team.examples.filesystem/plugin.xml +++ b/examples/org.eclipse.team.examples.filesystem/plugin.xml @@ -35,6 +35,62 @@ id="org.eclipse.team.examples.filesystem.FileSystemProvider"> </repository> </extension> + +<!-- *************** Deployment Provider **************** --> + <extension + point="org.eclipse.team.core.deployment"> + <deployment + class="org.eclipse.team.examples.filesystem.deployment.FileSystemDeploymentProvider" + id="org.eclipse.team.examples.filesystem.FileSystemDeploymentProvider" + name="%nonVersioningProvider"> + </deployment> + </extension> + +<!-- *************** Deployment ObjectContributions **************** --> + <extension + point="org.eclipse.ui.popupMenus"> + <objectContribution + objectClass="org.eclipse.core.resources.IContainer" + adaptable="true" + id="org.eclipse.team.examples.filesystem.ResourceContributions"> + <menu + label="Deployment Example" + path="additions" + id="example.deployment"> + <separator name="group1"/> + <separator name="group2"/> + </menu> + <action + label="Connect..." + tooltip="Deployment Actions" + menubarPath="example.deployment/group2" + class="org.eclipse.team.examples.filesystem.deployment.DeployAction" + id="org.eclipse.team.examples.filesystem.deploy"> + </action> + <action + label="Disconnect..." + tooltip="Deployment Actions" + menubarPath="example.deployment/group2" + class="org.eclipse.team.examples.filesystem.deployment.UnDeployAction" + id="org.eclipse.team.examples.filesystem.undeploy"> + </action> + <action + label="Upload" + tooltip="Deployment Actions" + menubarPath="example.deployment/group1" + class="org.eclipse.team.examples.filesystem.deployment.NullAction" + id="org.eclipse.team.examples.filesystem.undeploy"> + </action> + <action + label="Download" + tooltip="Deployment Actions" + menubarPath="example.deployment/group1" + class="org.eclipse.team.examples.filesystem.deployment.NullAction" + id="org.eclipse.team.examples.filesystem.undeploy"> + </action> + </objectContribution> + </extension> + <!-- *************** POPUP MENUS **************** --> <extension point="org.eclipse.ui.popupMenus"> @@ -82,7 +138,7 @@ class="org.eclipse.team.examples.filesystem.ui.DisconnectAction" menubarPath="team.main/group2" id="org.eclipse.team.examples.filesystem.unmanage"> - </action> + </action> </objectContribution> </extension> <!-- *************** CONFIGURATION WIZARD **************** --> @@ -114,5 +170,4 @@ </filter> </page> </extension> - </plugin> diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileModificationValidator.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileModificationValidator.java index 6020049bd..909e30733 100644 --- a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileModificationValidator.java +++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileModificationValidator.java @@ -20,7 +20,6 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.team.core.RepositoryProvider; import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.core.simpleAccess.SimpleAccessOperations; /** * This class models a sentry that verifies whether resources are available for editing or overwriting. @@ -32,15 +31,13 @@ public final class FileModificationValidator implements IFileModificationValidat //Used to avoid creating multiple copies of the OK status: private static final IStatus OK_STATUS = new Status(Status.OK, FileSystemPlugin.ID, Status.OK, Policy.bind("ok"), null); //$NON-NLS-1$ - private RepositoryProvider provider; private SimpleAccessOperations operations; /** * Constructor for FileModificationValidator. */ public FileModificationValidator(RepositoryProvider provider) { - this.provider = provider; - operations = provider.getSimpleAccess(); + operations = ((FileSystemProvider)provider).getSimpleAccess(); } /** diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemProvider.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemProvider.java index 2fae985be..60f64c48b 100644 --- a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemProvider.java +++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemProvider.java @@ -19,7 +19,6 @@ import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.team.core.RepositoryProvider; import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.core.simpleAccess.SimpleAccessOperations; /** * This example illustrates how to create a concrete implementation of a <code>RepositoryProvider</code> diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemRemoteResource.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemRemoteResource.java index d8b2db061..5df6b25e6 100644 --- a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemRemoteResource.java +++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemRemoteResource.java @@ -10,28 +10,18 @@ *******************************************************************************/ package org.eclipse.team.examples.filesystem; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import org.eclipse.core.resources.IFile; 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.NullProgressMonitor; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.*; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.IRemoteResource; /** * Class represents a handle to a <code>java.io.File</code> that conforms to - * the <code>org.eclipse.team.core.IRemoteResource</code> interface. + * the <code>org.eclipse.team.core.IResourceVariant</code> interface. */ -public class FileSystemRemoteResource implements IRemoteResource, IStorage { +public class FileSystemRemoteResource implements IAdaptable, IStorage { // the file object in which the data is stored on the disk private File ioFile; @@ -66,7 +56,7 @@ public class FileSystemRemoteResource implements IRemoteResource, IStorage { * Returns an input stream containing the contents of the remote resource. * The remote resource must be a file. * - * @see org.eclipse.team.core.sync.IRemoteResource#getContents(IProgressMonitor) + * @see org.eclipse.team.core.sync.IResourceVariant#getContents(IProgressMonitor) */ public InputStream getContents(IProgressMonitor progress) throws TeamException { if (isContainer()) @@ -88,14 +78,14 @@ public class FileSystemRemoteResource implements IRemoteResource, IStorage { } /** - * @see org.eclipse.team.core.sync.IRemoteResource#getName() + * @see org.eclipse.team.core.sync.IResourceVariant#getName() */ public String getName() { return ioFile.getName(); } /** - * @see org.eclipse.team.core.sync.IRemoteResource#isContainer() + * @see org.eclipse.team.core.sync.IResourceVariant#isContainer() */ public boolean isContainer() { return ioFile.isDirectory(); @@ -105,16 +95,16 @@ public class FileSystemRemoteResource implements IRemoteResource, IStorage { * Fetch the members of the remote resource. The remote resource must be a * container. * - * @see org.eclipse.team.core.sync.IRemoteResource#members(IProgressMonitor) + * @see org.eclipse.team.core.sync.IResourceVariant#members(IProgressMonitor) */ - public IRemoteResource[] members(IProgressMonitor progress) throws TeamException { + public FileSystemRemoteResource[] members(IProgressMonitor progress) throws TeamException { // Make sure we have a container if (!isContainer()) throw new TeamException(Policy.bind("RemoteResource.mustBeFolder", ioFile.getName())); //$NON-NLS-1$ // convert the File children to remote resource children File[] members = ioFile.listFiles(); - IRemoteResource[] result = new IRemoteResource[members.length]; + FileSystemRemoteResource[] result = new FileSystemRemoteResource[members.length]; for (int i = 0; i < members.length; i++) { result[i] = new FileSystemRemoteResource(members[i]); } diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemSimpleAccessOperations.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemSimpleAccessOperations.java index 87852220a..b80a9d2e5 100644 --- a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemSimpleAccessOperations.java +++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemSimpleAccessOperations.java @@ -10,21 +10,11 @@ *******************************************************************************/ package org.eclipse.team.examples.filesystem; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.resources.*; +import org.eclipse.core.runtime.*; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.IRemoteResource; -import org.eclipse.team.internal.core.simpleAccess.SimpleAccessOperations; -import org.eclipse.team.examples.filesystem.Policy; /** * SimpleAccessOperations is not part of the Team API. We use it here because it provides @@ -95,7 +85,7 @@ public class FileSystemSimpleAccessOperations implements SimpleAccessOperations } } else if (depth > 0) { //Assume that resources are either files or containers. //If the resource is a container, copy its children over. - IRemoteResource[] estranged = remote.members(progress); + FileSystemRemoteResource[] estranged = remote.members(progress); IResource[] children = new IResource[estranged.length]; if (resources[i].getType() == IResource.PROJECT) { diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemSubscriber.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemSubscriber.java new file mode 100644 index 000000000..50ab30efb --- /dev/null +++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/FileSystemSubscriber.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * 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.examples.filesystem; + +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.core.synchronize.IResourceVariantComparator; +import org.eclipse.team.internal.core.subscribers.caches.SyncTreeSubscriber; + + +public class FileSystemSubscriber extends SyncTreeSubscriber { + + /* (non-Javadoc) + * @see org.eclipse.team.internal.core.subscribers.caches.SyncTreeSubscriber#getRemoteResource(org.eclipse.core.resources.IResource) + */ + public IResourceVariant getRemoteResource(IResource resource) throws TeamException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.core.subscribers.caches.SyncTreeSubscriber#getBaseResource(org.eclipse.core.resources.IResource) + */ + public IResourceVariant getBaseResource(IResource resource) throws TeamException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.core.subscribers.caches.SyncTreeSubscriber#hasRemote(org.eclipse.core.resources.IResource) + */ + protected boolean hasRemote(IResource resource) throws TeamException { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.core.subscribers.caches.SyncTreeSubscriber#getResourceComparator() + */ + public IResourceVariantComparator getResourceComparator() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.Subscriber#getName() + */ + public String getName() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.Subscriber#isSupervised(org.eclipse.core.resources.IResource) + */ + public boolean isSupervised(IResource resource) throws TeamException { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.Subscriber#roots() + */ + public IResource[] roots() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.Subscriber#refresh(org.eclipse.core.resources.IResource[], int, org.eclipse.core.runtime.IProgressMonitor) + */ + public void refresh(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException { + // TODO Auto-generated method stub + + } +} diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/SimpleAccessOperations.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/SimpleAccessOperations.java new file mode 100644 index 000000000..ce5f0c0d4 --- /dev/null +++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/SimpleAccessOperations.java @@ -0,0 +1,267 @@ +/******************************************************************************* + * 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.examples.filesystem; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.team.core.TeamException; + +/* + * This class represents provisional API. Its here to allow experimentation with 3rd party tools + * calling providers in a repository neutral manner. + * + * A provider is not required to implement this API. + * Implementers, and those who reference it, do so with the awareness that this class may be + * removed or substantially changed at future times without warning. + * + * The <code>SimpleAccessOperations</code> class exposes a basic repository model that + * providers may implement to allow third-party plugins to perform repository operations + * programmatically. For example, a code generation tool may want to get source + * files before generating the code, and check-in the results. If a provider plugin does + * not adhere to the <i>semantics</i> of the <code>SimpleAccessOperations</code> class + * as described, they are free to opt out of implementing it. + * + * @since 2.0 + */ +public interface SimpleAccessOperations { + /* + * Updates the local resource to have the same content as the corresponding remote + * resource. Where the local resource does not exist, this method will create it. + * <p> + * If the remote resource is a container (e.g. folder or project) this operation is equivalent + * to getting each non-container member of the remote resource, thereby updating the + * content of existing local members, creating local members to receive new remote resources, + * and deleting local members that no longer have a corresponding remote resource.</p> + * <p> + * The method is applied to all resources satisfying the depth parameter, described above.</p> + * <p> + * Interrupting the method (via the progress monitor) may lead to partial, but consistent, results.</p> + * + * @param resources an array of local resources to update from the corresponding remote + * resources. + * @param depth the depth to traverse the given resources, taken from <code>IResource</code> + * static constants. + * @param progress a progress monitor to indicate the duration of the operation, or + * <code>null</code> if progress reporting is not required. + * @throws TeamException if there is a problem getting one or more of the resources. The + * exception will contain multiple statuses, one for each resource in the <code>resources</code> + * array. Possible status codes include: + * <ul> + * <li>NO_REMOTE_RESOURCE</li> + * <li>IO_FAILED</li> + * <li>NOT_AUTHORIZED</li> + * <li>UNABLE</li> + * </ul> + */ + public void get(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException; + + /* + * Changes the state of the local resource from checked-in to checked-out and transfers the content + * of the remote resource to the local resource. + * <p> + * Where no corresponding local resource exists in the workspace, one is created (including any + * intermediate parent containers) to receive the contents of the remote resource.</p> + * <p> + * Implementations may optimistically only flag the state change locally and rely on resolving conflicts + * during check-in, or they may pessimistically also checkout or lock the remote resource during a + * local resource checkout to avoid conflicts. The provider API does not subscribe to either model + * and supports each equally.</p> + * <p> + * Where checkout is applied to a resource that is already checked-out the method has no + * effect.</p> + * + * @param resources the array of local resources to be checked-out. + * @param depth the depth to traverse the given resources, taken from <code>IResource</code> + * constants. + * @param progress a progress monitor to indicate the duration of the operation, or + * <code>null</code> if progress reporting is not required. + * @throws TeamProviderException if there is a problem checking-out one or more of the resources. + * The exception will contain multiple statuses, one for each resource in the <code>resources</code> + * array. Possible status codes include: + * <ul> + * <li>NOT_CHECKED_IN</li> + * <li>NO_REMOTE_RESOURCE</li> + * <li>IO_FAILED</li> + * <li>NOT_AUTHORIZED</li> + * <li>UNABLE</li> + * </ul> + * @see checkin(IResource[], int, IProgressMonitor) + */ + public void checkout(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException; + + /* + * Transfers the content of the local resource to the corresponding remote resource, and changes the + * state of the local resource from checked-out to checked-in. + * <p> + * If a remote resource does not exist this method creates a new remote resource with the same content + * as the given local resource. The local resource is said to <i>correspond</i> to the new remote resource.</p> + * <p> + * Where providers deal with stores that check-out or lock resources this method is an opportunity + * to transfer the content and make the corresponding remote check-in or unlock. It is envisaged that + * where the server maintains resource versions, checkin creates a new version of the remote resource.</p> + * <p> + * Note that some providers may <em>require</em> that a resource is checked-out before it can be + * checked-in. However, all providers must support the explicit checking out a resource before checking + * it in (e.g., even if the check out is a no-op).</p> + * + * @param resources an array of local resources to be checked-in. + * @param the depth to traverse the given resources, taken from <code>IResource</code> + * constants. + * @param progress a progress monitor to indicate the duration of the operation, or + * <code>null</code> if progress reporting is not required. + * @throws TeamException if there is a problem checking-in one or more of the resources. + * The exception will contain multiple statuses, one for each resource in the <code>resources</code> + * array. Possible status codes include: + * <ul> + * <li>NOT_CHECKED_OUT</li> + * <li>IO_FAILED</li> + * <li>NOT_AUTHORIZED</li> + * <li>UNABLE</li> + * </ul> + * @see checkout(IResource[], int, IProgressMonitor) + */ + public void checkin(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException; + + /* + * Changes the state of the local resource from checked-out to checked-in without updating the contents + * of the remote resource. + * <p> + * Note that where the provider is a versioning provider, it is envisaged (though not required) that the + * uncheckout operation does not create a new version.</p> + * <p> + * Note also that <code>uncheckout()</code> does not affect the content of the local resource. The + * caller is required to perform a <code>get()</code> to revert the local resource if that is required + * (otherwise the local resource will be left with the changes that were made while the remote resource + * was checked-out. Furthermore, it is valid to call <code>uncheckout()</code> with an + * <code>IResource</code> that does not exist locally.</p> + * + * @param resources an array of the local resources that are to be unchecked-out. + * @param depth the depth to traverse the given resources, taken from <code>IResource</code> + * constants. + * @param progress a progress monitor to indicate the duration of the operation, or + * <code>null</code> if progress reporting is not required. + * @throws TeamProviderException if there is a problem undoing the check-out of one or more of + * the resources. The exception will contain multiple statuses, one for each resource in the + * <code>resources</code> array. Possible status codes include: + * <ul> + * <li>NOT_CHECKED_OUT</li> + * <li>IO_FAILED</li> + * <li>NOT_AUTHORIZED</li> + * <li>UNABLE</li> + * </ul> + * @see checkin(IResource) + * @see uncheckout(IResource) + */ + public void uncheckout(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException; + + /* + * Deletes the remote resource corresponding to the given local resource. + * <p> + * The notion of delete is simply to make the remote resource unavailable. Where the provider + * supports versioning it is not specified whether the delete operation makes the version + * temporarily or forever unavailable, or indeed whether the entire history is made unavailable.</p> + * <p> + * Note that the <code>IResource</code>'s passed as arguments may be non-existant in the + * workbench, the typical case is when such a resource has been received in a core callback.</p> + * <p> + * The resource may be checked-in or checked-out prior to deletion. The local resource is not + * deleted by this method.</p> + * <p> + * Resource deletions are inherently deep.</p> + * + * @param resources the array of resources whose corresponding remote resources are to be deleted. + * @param progress a progress monitor to indicate the duration of the operation, or + * <code>null</code> if progress reporting is not required. + * @throws TeamProviderException if there is a problem deleting one or more of + * the resources. The exception will contain multiple statuses, one for each resource in the + * <code>resources</code> array. Possible status codes include: + * <ul> + * <li>NO_REMOTE_RESOURCE</li> + * <li>IO_FAILED</li> + * <li>NOT_AUTHORIZED</li> + * <li>UNABLE</li> + * </ul> + */ + public void delete(IResource[] resources, IProgressMonitor progress) throws TeamException; + + /* + * Informs the provider that a local resource's name or path has changed. + * <p> + * Some providers, such as versioning providers, may require this information to track the resource + * across name changes.</p> + * <p> + * Note that this method is always called <em>after</em> the local resource has been moved.</p> + * + * @param source the full name of the resource before it was moved. + * @param target the resource that was moved. + * @param progress a progress monitor to indicate the duration of the operation, or + * <code>null</code> if progress reporting is not required. + * @throws TeamProviderException if there is a problem recording the move. The exception will + * contain a single status. Possible status codes are: + * <ul> + * <li>NO_REMOTE_RESOURCE</li> + * <li>IO_FAILED</li> + * <li>NOT_AUTHORIZED</li> + * <li>UNABLE</li> + * </ul> + */ + public void moved(IPath source, IResource target, IProgressMonitor progress) throws TeamException; + + /* + * Implementor's Note: + * The following methods are required to return promptly (i.e., they may be used to determine the state of + * a resource in a UI where long delays are unacceptable). Implementations may cache these values + * and update the cache on an explicit call to #refreshState(). + * + * They are currently listed in the provider API, however, they may be moved to a new or different + * interface in the future to better reflect their UI-orientation. + */ + + /* + * Answers if the remote resource state is checked-out. If the resource has never been checked in this + * method will return <code>true</code>. + * <p> + * It is undefined whether this method tests for a resource being checked out to this workspace + * or any workspace.</p> + * + * @param resource the local resource to test. + * @return <code>true</code> if the resource is checked-out and <code>false</code> if it is not. + * @see checkout(IResource[], int, IProgressMonitor) + */ + public boolean isCheckedOut(IResource resource); + + /* + * Answers whether the resource has a corresponding remote resource. + * <p> + * Before a resource is checked-in, the resource will occur locally but not remotely, and calls to this + * method will return <code>false</code>. Once a local resource is checked in (and assuming the local + * local resource is not moved or the remote resource deleted) there will be a corresponding remote + * resource and this method returns <code>true</code>.</p> + * + * @param resource the local resource to test. + * @return <code>true</code> if the local resource has a corresponding remote resource, + * and <code>false</code> otherwise. + * @see checkin(IResource[], int, IProgressMonitor) + * @see refreshState(IResource[], int, IProgressMonitor) + */ + public boolean hasRemote(IResource resource); + + /* + * Answer if the local resource currently has a different timestamp to the base timestamp + * for this resource. + * + * @param resource the resource to test. + * @return <code>true</code> if the resource has a different modification + * timestamp, and <code>false</code> otherwise. + */ + public boolean isDirty(IResource resource); +} diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/deployment/DeployAction.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/deployment/DeployAction.java new file mode 100644 index 000000000..7fc9c2790 --- /dev/null +++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/deployment/DeployAction.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * 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.examples.filesystem.deployment; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.team.core.*; +import org.eclipse.team.internal.ui.actions.TeamAction; +import org.eclipse.ui.IActionDelegate; + +public class DeployAction extends TeamAction implements IActionDelegate { + + public void run(IAction action) { + IContainer container = (IContainer)getSelectedResources()[0]; + IDeploymentProviderManager manager = Team.getDeploymentManager(); + FileSystemDeploymentProvider provider = new FileSystemDeploymentProvider(); + try { + manager.map(container, provider); + } catch (TeamException e) { + ErrorDialog.openError(getShell(), "Error", "Mapping", e.getStatus()); + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.actions.TeamAction#isEnabled() + */ + protected boolean isEnabled() throws TeamException { + IResource[] resources = getSelectedResources(); + if(resources.length == 1) { + IResource resource = resources[0]; + IDeploymentProviderManager manager = Team.getDeploymentManager(); + if(manager.getMappedTo(resource, FileSystemDeploymentProvider.ID)) { + return false; + } + } + return true; + } +}
\ No newline at end of file diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/deployment/FileSystemDeploymentProvider.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/deployment/FileSystemDeploymentProvider.java new file mode 100644 index 000000000..19848f476 --- /dev/null +++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/deployment/FileSystemDeploymentProvider.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * 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.examples.filesystem.deployment; + +import org.eclipse.team.core.DeploymentProvider; +import org.eclipse.team.internal.core.IMemento; + +public class FileSystemDeploymentProvider extends DeploymentProvider { + + public final static String ID = "org.eclipse.team.examples.filesystem.FileSystemDeploymentProvider"; + + public String getID() { + return ID; + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.DeploymentProvider#init() + */ + public void init() { + // TODO Auto-generated method stub + System.out.println("Initialized " + getName()); + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.DeploymentProvider#dispose() + */ + public void dispose() { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.DeploymentProvider#saveState(org.eclipse.team.core.IMemento) + */ + public void saveState(IMemento memento) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.DeploymentProvider#restoreState(org.eclipse.team.core.IMemento) + */ + public void restoreState(IMemento memento) { + // TODO Auto-generated method stub + + } +} diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/deployment/NullAction.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/deployment/NullAction.java new file mode 100644 index 000000000..9216d190a --- /dev/null +++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/deployment/NullAction.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * 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.examples.filesystem.deployment; + +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.team.core.IDeploymentProviderManager; +import org.eclipse.team.core.Team; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.internal.ui.actions.TeamAction; +import org.eclipse.ui.IActionDelegate; + +public class NullAction extends TeamAction implements IActionDelegate { + + public void run(IAction action) { + MessageDialog.openQuestion(getShell(), "Action Run", "Action Run"); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.actions.TeamAction#isEnabled() + */ + protected boolean isEnabled() throws TeamException { + IResource[] resources = getSelectedResources(); + if(resources.length == 1) { + IResource resource = resources[0]; + IDeploymentProviderManager manager = Team.getDeploymentManager(); + if(! manager.getMappedTo(resource, FileSystemDeploymentProvider.ID)) { + return false; + } + } + return true; + } +}
\ No newline at end of file diff --git a/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/deployment/UnDeployAction.java b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/deployment/UnDeployAction.java new file mode 100644 index 000000000..5466a25fc --- /dev/null +++ b/examples/org.eclipse.team.examples.filesystem/src/org/eclipse/team/examples/filesystem/deployment/UnDeployAction.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * 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.examples.filesystem.deployment; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.team.core.DeploymentProvider; +import org.eclipse.team.core.IDeploymentProviderManager; +import org.eclipse.team.core.Team; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.internal.ui.actions.TeamAction; +import org.eclipse.ui.IActionDelegate; + +public class UnDeployAction extends TeamAction implements IActionDelegate { + + public void run(IAction action) { + IContainer container = (IContainer)getSelectedResources()[0]; + IDeploymentProviderManager manager = Team.getDeploymentManager(); + try { + DeploymentProvider[] providers = manager.getMappings(container, FileSystemDeploymentProvider.ID); + for (int i = 0; i < providers.length; i++) { + DeploymentProvider provider = providers[i]; + manager.unmap(container, provider); + } + } catch (TeamException e) { + ErrorDialog.openError(getShell(), "Error", "Un-Mapping", e.getStatus()); + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.actions.TeamAction#isEnabled() + */ + protected boolean isEnabled() throws TeamException { + IResource[] resources = getSelectedResources(); + if(resources.length == 1) { + IResource resource = resources[0]; + IDeploymentProviderManager manager = Team.getDeploymentManager(); + if(! manager.getMappedTo(resource, FileSystemDeploymentProvider.ID)) { + return false; + } + } + return true; + } +}
\ No newline at end of file diff --git a/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/core/TeamTest.java b/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/core/TeamTest.java index 3370456bb..35727acdb 100644 --- a/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/core/TeamTest.java +++ b/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/core/TeamTest.java @@ -10,32 +10,35 @@ *******************************************************************************/ package org.eclipse.team.tests.core; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.io.*; +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.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Status; +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.eclipse.core.resources.*; +import org.eclipse.core.runtime.*; import org.eclipse.core.tests.harness.EclipseWorkspaceTest; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.IRemoteResource; public class TeamTest extends EclipseWorkspaceTest { protected static IProgressMonitor DEFAULT_MONITOR = new NullProgressMonitor(); protected static final IProgressMonitor DEFAULT_PROGRESS_MONITOR = new NullProgressMonitor(); + public static Test suite(Class c) { + String testName = System.getProperty("eclipse.team.testName"); + if (testName == null) { + TestSuite suite = new TestSuite(c); + return suite; + } else { + try { + return (Test)c.getConstructor(new Class[] { String.class }).newInstance(new Object[] {testName}); + } catch (Exception e) { + fail(e.getMessage()); + // Above will throw so below is never actually reached + return null; + } + } + } public TeamTest() { super(); @@ -145,22 +148,6 @@ public class TeamTest extends EclipseWorkspaceTest { } } - // Assert that the two containers have equal contents - protected void assertEquals(IRemoteResource container1, IResource container2) throws CoreException, TeamException { - if (container2.getType() == IResource.FILE) { - // Ignore .project file - if (container2.getName().equals(".project")) - return; - assertTrue(compareContent(container1.getContents(DEFAULT_MONITOR), ((IFile) container2).getContents())); - } else { - IRemoteResource[] remoteResources = container1.members(DEFAULT_MONITOR); - IResource[] localResources = ((IFolder) container2).members(); - for (int i = 0; i < localResources.length; i++) { - assertEquals(remoteResources[i], localResources[i]); - } - } - } - public void appendText(IResource resource, String text, boolean prepend) throws CoreException, IOException { IFile file = (IFile) resource; InputStream in = file.getContents(); diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/AllTests.java b/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/synchronize/AllTeamSynchronizeTests.java index 8b11d77fc..24f9123be 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/AllTests.java +++ b/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/synchronize/AllTeamSynchronizeTests.java @@ -8,25 +8,35 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.team.tests.ccvs.ui.old; - +package org.eclipse.team.tests.ui.synchronize; import junit.framework.Test; import junit.framework.TestSuite; -public class AllTests extends TestSuite { - public static Test suite() { - TestSuite suite = new TestSuite(); - suite.addTestSuite(SyncTests.class); - suite.addTestSuite(WorkflowTests.class); - //suite.addTestSuite(CommandTests.class); - return new BenchmarkTestSetup(suite); - } - - public AllTests(String name) { +import org.eclipse.core.tests.harness.EclipseWorkspaceTest; + +public class AllTeamSynchronizeTests extends EclipseWorkspaceTest { + + /** + * Constructor for CVSClientTest. + */ + public AllTeamSynchronizeTests() { + super(); + } + + /** + * Constructor for CVSClientTest. + * @param name + */ + public AllTeamSynchronizeTests(String name) { super(name); } - public AllTests() { - super(); + + public static Test suite() { + TestSuite suite = new TestSuite(); + suite.addTest(TestDiffNodePresentationModel.suite()); + suite.addTest(SyncInfoSetContentProviderTest.suite()); + return suite; } } + diff --git a/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/synchronize/SyncInfoSetContentProviderTest.java b/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/synchronize/SyncInfoSetContentProviderTest.java new file mode 100644 index 000000000..2d4d6421d --- /dev/null +++ b/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/synchronize/SyncInfoSetContentProviderTest.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * 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.tests.ui.synchronize; + +import java.util.Iterator; +import java.util.List; + +import junit.framework.Test; + +import org.eclipse.core.resources.*; +import org.eclipse.team.core.synchronize.SyncInfoTree; +import org.eclipse.team.ui.synchronize.viewers.SynchronizeModelProvider; +import org.eclipse.team.ui.synchronize.viewers.CompressedFoldersModelProvider; + +/** + * Tests for the SyncInfoSet content providers. + */ +public class SyncInfoSetContentProviderTest extends TestDiffNodePresentationModel { + + /** + * Constructor for CVSProviderTest + */ + public SyncInfoSetContentProviderTest() { + super(); + } + + /** + * Constructor for CVSProviderTest + */ + public SyncInfoSetContentProviderTest(String name) { + super(name); + } + + public static Test suite() { + return suite(SyncInfoSetContentProviderTest.class); + } + + /* (non-Javadoc) + * @see org.eclipse.team.tests.ui.synchronize.TestDiffNodePresentationModel#getDiffNodeController() + */ + protected SynchronizeModelProvider getDiffNodeController(SyncInfoTree set) { + return new CompressedFoldersModelProvider(set); + } + + private void assertFolderPresent(IFolder folder, List resources) { + // First, if the folder is out-of-sync, it should be visible + for (Iterator iter = resources.iterator(); iter.hasNext();) { + IResource resource = (IResource) iter.next(); + if (resource.equals(folder)) { + // The folder should be present. + // Remove it since it has been verified + iter.remove(); + return; + } + } + // If the folder contains a file in the list, it is also OK + for (Iterator iter = resources.iterator(); iter.hasNext();) { + IResource resource = (IResource) iter.next(); + if (resource.getType() == IResource.FILE && resource.getParent().equals(folder)) { + // The compressed folder is valid since it contains an out-of-sync file + // However, the resource is left since it has not been verified (only it's parent) + return; + } + } + fail("Folder " + folder.getFullPath() + " should not be visible but is."); + } + + private void assertFilePresent(IResource itemResource, List resources) { + for (Iterator iter = resources.iterator(); iter.hasNext();) { + IResource resource = (IResource) iter.next(); + if (resource.equals(itemResource)) { + // The resource has been verified so it can be removed + iter.remove(); + return; + } + } + fail("Resource " + itemResource.getFullPath() + " should not be visible but is."); + } + + private void assertProjectPresent(IProject project, List resources) { +// First, if the project is out-of-sync, it should be visible + for (Iterator iter = resources.iterator(); iter.hasNext();) { + IResource resource = (IResource) iter.next(); + if (resource.equals(project)) { + // The folder should be present. + // Remove it since it has been verified + iter.remove(); + return; + } + } + for (Iterator iter = resources.iterator(); iter.hasNext();) { + IResource resource = (IResource) iter.next(); + if (resource.getProject().equals(project)) { + return; + } + } + fail("Project " + project.getName() + " should not be visible but is."); + } +} diff --git a/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/synchronize/TestDiffNodePresentationModel.java b/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/synchronize/TestDiffNodePresentationModel.java new file mode 100644 index 000000000..833849309 --- /dev/null +++ b/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/synchronize/TestDiffNodePresentationModel.java @@ -0,0 +1,209 @@ +/******************************************************************************* + * 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.tests.ui.synchronize; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.Test; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.swt.widgets.Item; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.internal.ui.Utils; +import org.eclipse.team.tests.core.TeamTest; +import org.eclipse.team.tests.ui.views.ContentProviderTestView; +import org.eclipse.team.tests.ui.views.TestTreeViewer; +import org.eclipse.team.ui.synchronize.viewers.*; + + +public class TestDiffNodePresentationModel extends TeamTest { + + private ContentProviderTestView view; + private SyncInfoTree set; + private TreeViewerAdvisor configuration; + + public TestDiffNodePresentationModel() { + super(); + } + + public TestDiffNodePresentationModel(String name) { + super(name); + } + + public static Test suite() { + return suite(TestDiffNodePresentationModel.class); + } + + /* (non-Javadoc) + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + this.set = new SyncInfoTree(); + this.configuration = new TreeViewerAdvisor(set) { + protected SynchronizeModelProvider getDiffNodeController() { + return TestDiffNodePresentationModel.this.getDiffNodeController(set); + } + }; + view = ContentProviderTestView.findViewInActivePage(null); + configuration.initializeViewer(view.getViewer()); + } + + /* (non-Javadoc) + * @see junit.framework.TestCase#tearDown() + */ + protected void tearDown() throws Exception { + set = null; + configuration.dispose(); + super.tearDown(); + } + + protected SynchronizeModelProvider getDiffNodeController(SyncInfoTree set) { + return new HierarchicalModelProvider(set); + } + + /* + * This method creates a project with the given resources, imports + * it to CVS and checks it out + */ + protected IProject createProject(String prefix, String[] resources) throws CoreException { + IProject project = getUniqueTestProject(prefix); + buildResources(project, resources, true); + return project; + } + + /* + * Create a test project using the currently running test case as the project name prefix + */ + protected IProject createProject(String[] resources) throws CoreException { + return createProject(getName(), resources); + } + + private void adjustSet(SyncInfoSet set, IProject project, String[] resourceStrings, int[] syncKind) throws TeamException { + IResource[] resources = buildResources(project, resourceStrings); + try { + set.beginInput(); + for (int i = 0; i < resources.length; i++) { + IResource resource = resources[i]; + int kind = syncKind[i]; + if (kind == SyncInfo.IN_SYNC) { + set.remove(resource); + } else { + SyncInfo newInfo = new TestSyncInfo(resource, kind); + set.add(newInfo); + } + } + } finally { + set.endInput(null); + } + } + + /** + * Ensure that the resource + * @param resources + */ + protected void assertProperVisibleItems() { + IResource[] resources = set.getResources(); + List resourceList = new ArrayList(); + for (int i = 0; i < resources.length; i++) { + IResource resource = resources[i]; + resourceList.add(resource); + } + TestTreeViewer viewer = view.getViewer(); + Item[] items = viewer.getRootItems(); + if (resources.length == 0) { + assertTrue("There are items visible when there should not be.", items.length == 0); + return; + } + // Test that all items in the tree are expected + for (int i = 0; i < items.length; i++) { + Item item = items[i]; + assertThatAllOutOfSyncResourcesAreShown(item, resourceList); + } + // Test that all expected resources and their parents are present + assertTrue("The tree did not contain all expected resources: " + resourceList.toString(), resourceList.isEmpty()); + } + + /** + * Traverse every element shown in the view and ensure that every out-of-sync + * resource in the set is at least shown. This doesn't test the actual logical + * organization, but does ensure that all out-of-sync resources are shown only + * once. + */ + protected void assertThatAllOutOfSyncResourcesAreShown(Item item, List outOfSyncResources) { + Object node = item.getData(); + SyncInfo info = (SyncInfo)Utils.getAdapter(node, SyncInfo.class); + if(info != null) { + assertTrue("The tree contained an out-of-sync resource that wasn't in the set", outOfSyncResources.remove(info.getLocal())); + } + Item[] children = view.getViewer().getChildren(item); + for (int i = 0; i < children.length; i++) { + Item child = children[i]; + assertThatAllOutOfSyncResourcesAreShown(child, outOfSyncResources); + } + } + + public void testNestedFolder() throws CoreException { + IProject project = createProject(new String[]{"file.txt", "folder1/file2.txt", "folder1/folder2/file3.txt"}); + adjustSet(set, project, + new String[]{"file.txt"}, + new int[]{SyncInfo.OUTGOING | SyncInfo.CHANGE}); + assertProperVisibleItems(); + adjustSet(set, project, + new String[]{"folder1/file2.txt", "folder1/folder2/file3.txt"}, + new int[]{SyncInfo.OUTGOING | SyncInfo.CHANGE, SyncInfo.OUTGOING | SyncInfo.CHANGE}); + assertProperVisibleItems(); + adjustSet(set, project, + new String[]{"folder1/file2.txt"}, + new int[]{SyncInfo.IN_SYNC,}); + assertProperVisibleItems(); + } + + public void testParentRemovalWithChildRemaining() throws CoreException { + IProject project = createProject(new String[]{"file.txt", "folder1/file2.txt", "folder1/folder2/file3.txt"}); + adjustSet(set, project, + new String[]{"folder1/folder2/", "folder1/folder2/file3.txt"}, + new int[]{SyncInfo.CONFLICTING | SyncInfo.CHANGE, SyncInfo.CONFLICTING | SyncInfo.CHANGE}); + assertProperVisibleItems(); + + adjustSet(set, project, + new String[]{"folder1/folder2/", "folder1/folder2/file3.txt"}, + new int[]{SyncInfo.IN_SYNC, SyncInfo.OUTGOING | SyncInfo.CHANGE}); + assertProperVisibleItems(); + } + + public void testEmptyFolderChange() throws CoreException { + IProject project = createProject(new String[]{"file.txt", "folder1/file2.txt", "folder1/folder2/file3.txt", "folder3/"}); + adjustSet(set, project, + new String[]{"folder1/folder2/", "folder1/folder2/file3.txt"}, + new int[]{SyncInfo.CONFLICTING | SyncInfo.CHANGE, SyncInfo.CONFLICTING | SyncInfo.CHANGE}); + assertProperVisibleItems(); + + adjustSet(set, project, + new String[]{"folder1/folder2/", "folder1/folder2/file3.txt"}, + new int[]{SyncInfo.IN_SYNC, SyncInfo.OUTGOING | SyncInfo.CHANGE}); + assertProperVisibleItems(); + + adjustSet(set, project, + new String[]{"folder1/folder2/file3.txt"}, + new int[]{SyncInfo.IN_SYNC}); + assertProperVisibleItems(); + + adjustSet(set, project, + new String[]{"folder3/"}, + new int[]{SyncInfo.INCOMING | SyncInfo.ADDITION}); + assertProperVisibleItems(); + } +} diff --git a/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/synchronize/TestSyncInfo.java b/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/synchronize/TestSyncInfo.java new file mode 100644 index 000000000..2a1150ac8 --- /dev/null +++ b/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/synchronize/TestSyncInfo.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * 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.tests.ui.synchronize; + +import org.eclipse.core.resources.IResource; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.core.synchronize.SyncInfo; + +public class TestSyncInfo extends SyncInfo { + + private int kind; + + public TestSyncInfo(IResource resource, int kind) throws TeamException { + super(resource, null, null, null); + this.kind = kind; + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.SyncInfo#calculateKind() + */ + protected int calculateKind() throws TeamException { + return this.kind; + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.SyncInfo#getKind() + */ + public int getKind() { + return kind; + } +} diff --git a/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/views/ContentProviderTestView.java b/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/views/ContentProviderTestView.java new file mode 100644 index 000000000..f6047411a --- /dev/null +++ b/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/views/ContentProviderTestView.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * 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.tests.ui.views; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.team.internal.ui.TeamUIPlugin; +import org.eclipse.ui.*; +import org.eclipse.ui.part.ViewPart; + +public class ContentProviderTestView extends ViewPart { + + public static final String VIEW_ID = "org.eclipse.team.tests.ui.views.ContentProviderTestView"; + + private TestTreeViewer viewer; + + public static ContentProviderTestView findViewInActivePage(IWorkbenchPage activePage) { + try { + if (activePage == null) { + activePage = TeamUIPlugin.getActivePage(); + if (activePage == null) return null; + } + IViewPart part = activePage.findView(VIEW_ID); + if (part == null) + part = activePage.showView(VIEW_ID); + return (ContentProviderTestView)part; + } catch (PartInitException pe) { + return null; + } + } + + public ContentProviderTestView() { + } + + public void createPartControl(Composite parent) { + viewer = new TestTreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + } + + public void setFocus() { + viewer.getControl().setFocus(); + } + + public TestTreeViewer getViewer() { + return viewer; + } +}
\ No newline at end of file diff --git a/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/views/TestTreeViewer.java b/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/views/TestTreeViewer.java new file mode 100644 index 000000000..7803f5ff2 --- /dev/null +++ b/tests/org.eclipse.team.tests.core/src/org/eclipse/team/tests/ui/views/TestTreeViewer.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * 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.tests.ui.views; + +import org.eclipse.compare.structuremergeviewer.DiffNode; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.widgets.*; + +public class TestTreeViewer extends TreeViewer { + + public TestTreeViewer(Composite parent) { + super(parent); + } + + public TestTreeViewer(Composite parent, int style) { + super(parent, style); + } + + public TestTreeViewer(Tree tree) { + super(tree); + } + + public Item[] getRootItems() { + expandAll(); + return getChildren(getControl()); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.AbstractTreeViewer#getChildren(org.eclipse.swt.widgets.Widget) + */ + public Item[] getChildren(Widget o) { + return super.getChildren(o); + } + + public boolean hasItemFor(DiffNode node) { + return findItem(node) != null; + } +} diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00007.html b/tests/org.eclipse.team.tests.cvs.core/html/00007.html index 68904853b..ef9fada1a 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00007.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00007.html @@ -4,7 +4,7 @@ <meta NAME="since" content=""> </head><body><h2>Check Out - prompts</h2> <p>Since: 3.0 M5<br> -Last Modified: $Date: 2003/11/19 21:41:32 $</p><body> +Last Modified: $Date: 2004/01/13 18:46:26 $</p><body> <ul> <li>Select a project in HEAD</li> <li>Perform a Checkout</li> diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00009.html b/tests/org.eclipse.team.tests.cvs.core/html/00009.html index 1b69e3947..2615c2c18 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00009.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00009.html @@ -4,7 +4,7 @@ <meta NAME="since" content=""> </head><body><h2>Remote resources</h2> <p>Since: 3.0 M5<br> -Last Modified: $Date: 2003/11/19 21:41:32 $</p><body> +Last Modified: $Date: 2004/01/13 18:46:26 $</p><body> <h4>Compare With... in Repositories view </h4> <p>Perform the following steps:</p> <ol> diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00011.html b/tests/org.eclipse.team.tests.cvs.core/html/00011.html index e8871cb6e..b0f3dc5f5 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00011.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00011.html @@ -4,7 +4,7 @@ <meta NAME="since" content=""> </head><body><h2>Sync View operations and selection</h2> <p>Since: 3.0 M5<br> -Last Modified: $Date: 2003/11/19 21:41:32 $</p><body> +Last Modified: $Date: 2004/01/13 18:46:26 $</p><body> <p>Ensure Commit and Update buttons:</p> <ul> <li>operate on all applicable visible changes</li> diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00013.html b/tests/org.eclipse.team.tests.cvs.core/html/00013.html index f99e30045..57143b3c6 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00013.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00013.html @@ -4,7 +4,7 @@ <meta NAME="since" content=""> </head><body><h2>Sync View operations and selection</h2> <p>Since: 3.0 M5<br> -Last Modified: $Date: 2003/11/19 21:41:32 $</p><body> +Last Modified: $Date: 2004/01/13 18:46:26 $</p><body> <ul> <li>Same scenarios as <a href="html/00011.html">Sync View operations and selection</a> except you can't commit. <li>Test mark as merged (ensure that it can work on large data sets diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00016.html b/tests/org.eclipse.team.tests.cvs.core/html/00016.html index 29bfb36ff..efbf71f31 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00016.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00016.html @@ -5,7 +5,7 @@ </head><body><h2>Sync View modes and working sets</h2> <p>Since: 3.0 M5<br> -Last Modified: $Date: 2003/11/19 21:41:32 $</p><body> +Last Modified: $Date: 2004/01/13 18:46:26 $</p><body> Ensure that choosing modes and working sets <ul> <li>result in proper filtering diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00018.html b/tests/org.eclipse.team.tests.cvs.core/html/00018.html index 35f57eda7..e69d3f179 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00018.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00018.html @@ -4,7 +4,7 @@ <meta NAME="since" content=""> </head><h2>Editor Linking</h2> <p>Since: 3.0 M5<br> -Last Modified: $Date: 2003/11/19 21:41:32 $</p><body> +Last Modified: $Date: 2004/01/13 18:46:26 $</p><body> <ol> <li>Open the Resource History view and enable editor linking</li> diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00019.html b/tests/org.eclipse.team.tests.cvs.core/html/00019.html index 9e5392a4d..187e5015b 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00019.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00019.html @@ -4,7 +4,7 @@ <meta NAME="since" content=""> </head><h2>Crash Recovery</h2> <p>Since: 3.0 M5<br> -Last Modified: $Date: 2003/11/19 21:41:32 $</p><body> +Last Modified: $Date: 2004/01/13 18:46:26 $</p><body> <p>Scenario 1</p> <ol> diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00021.html b/tests/org.eclipse.team.tests.cvs.core/html/00021.html index c7270ad03..aca77c05f 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00021.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00021.html @@ -4,7 +4,7 @@ <meta NAME="since" content=""> </head><h2>Close and disconnect</h2> <p>Since: 3.0 M5<br> -Last Modified: $Date: 2003/11/19 21:41:32 $</p><body> +Last Modified: $Date: 2004/01/13 18:46:26 $</p><body> <h4>Background refresh and disconnect</h4> <ol> diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00022.html b/tests/org.eclipse.team.tests.cvs.core/html/00022.html index d8dbbc2fd..d6efc6d52 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00022.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00022.html @@ -4,7 +4,7 @@ <meta NAME="since" content=""> </head><h2>Persistance and deletion</h2> <p>Since: <br> -Last Modified: $Date: 2003/11/19 21:41:32 $</p><body> +Last Modified: $Date: 2004/01/13 18:46:26 $</p><body> <ul> <li>Select a project and perform a merge. diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00023.html b/tests/org.eclipse.team.tests.cvs.core/html/00023.html index 1dc996d3e..c30bee182 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00023.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00023.html @@ -4,7 +4,7 @@ <meta NAME="since" content=""> </head><h2>Restarting Workbench</h2> <p>Since: <br> -Last Modified: $Date: 2003/11/20 22:20:45 $</p><body> +Last Modified: $Date: 2004/01/13 18:46:26 $</p><body> Answer comes here. diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00024.html b/tests/org.eclipse.team.tests.cvs.core/html/00024.html index 2942db38a..f4212d696 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00024.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00024.html @@ -4,7 +4,7 @@ <meta NAME="since" content=""> </head><h2>Annotate</h2> <p>Since: 3.0 M6<br> -Last Modified: $Date: 2003/11/20 22:20:45 $</p><body> +Last Modified: $Date: 2004/01/13 18:46:26 $</p><body> <h4>Annotate action should be available from</h4> <ul> diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00025.html b/tests/org.eclipse.team.tests.cvs.core/html/00025.html index e4c086d14..d62f4560c 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00025.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00025.html @@ -4,7 +4,7 @@ <meta NAME="since" content=""> </head><h2>Synchronize View Settings</h2> <p>Since: 3.0 M6<br> -Last Modified: $Date: 2003/11/20 22:20:45 $</p><body> +Last Modified: $Date: 2004/01/13 18:46:26 $</p><body> <h4>Saved between sessions</h4> <p>The following GUI preferences in the Synchronize View are persisted between workbench diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00026.html b/tests/org.eclipse.team.tests.cvs.core/html/00026.html index 2dd54b238..3836925ae 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00026.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00026.html @@ -4,7 +4,7 @@ <meta NAME="since" content=""> </head><h2>Sharing</h2> <p>Since: <br> -Last Modified: $Date: 2003/11/27 22:04:58 $</p><body> +Last Modified: $Date: 2004/01/13 18:46:26 $</p><body> Answer comes here. diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00027.html b/tests/org.eclipse.team.tests.cvs.core/html/00027.html index 35b50d6f9..d1d82b27c 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00027.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00027.html @@ -4,7 +4,7 @@ <meta NAME="since" content=""> </head><body><h2>Sharing as a subfolder</h2> <p>Since: 3.0 M6<br> -Last Modified: $Date: 2003/11/27 22:04:58 $</p> +Last Modified: $Date: 2004/01/13 18:46:26 $</p> <p>Perform the following steps:</p> <ol> diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00028.html b/tests/org.eclipse.team.tests.cvs.core/html/00028.html index 0aa50f2f6..f8dfc2d88 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00028.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00028.html @@ -4,7 +4,7 @@ <meta NAME="since" content=""> </head><h2>Reconnecting to existing</h2> <p>Since: 3.0 M6<br> -Last Modified: $Date: 2003/12/15 19:11:59 $</p><body> +Last Modified: $Date: 2004/01/13 18:46:26 $</p><body> <p> The following scenario represents how a user would reconnect a project that does not contain CVS meta-data to it's remote counterpart. It is assumed that the local project diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00029.html b/tests/org.eclipse.team.tests.cvs.core/html/00029.html index 0b4fd3464..5977ac65f 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00029.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00029.html @@ -4,7 +4,7 @@ <meta NAME="since" content=""> </head><h2>Patching</h2> <p>Since: 3.0 M6<br> -Last Modified: $Date: 2003/12/15 19:19:45 $</p><body> +Last Modified: $Date: 2004/01/13 18:46:26 $</p><body> Answer comes here. diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00029a.html b/tests/org.eclipse.team.tests.cvs.core/html/00029a.html index 135b9f8c1..b7bc11253 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00029a.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00029a.html @@ -4,7 +4,7 @@ <meta NAME="since" content=""> </head><h2>Server version compatibiliity</h2> <p>Since: M6<br> -Last Modified: $Date: 2003/11/27 22:04:58 $</p><body> +Last Modified: $Date: 2004/01/13 18:46:26 $</p><body> This test is to ensure that the ssh2 connection method properly delagates to ssh1 when the server only supports ssh1. diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00030.html b/tests/org.eclipse.team.tests.cvs.core/html/00030.html index e2ca35963..6d78d13c8 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00030.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00030.html @@ -4,7 +4,7 @@ <meta NAME="since" content=""> </head><h2>Importing a zip over a shared project</h2> <p>Since: 3.0 M6<br> -Last Modified: $Date: 2003/12/15 19:19:45 $</p><body> +Last Modified: $Date: 2004/01/13 18:46:26 $</p><body> <p>This scenario captures one means of patching. It assumes that a zip file contains a previous version of a project that has been modified in some way and added to diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00030a.html b/tests/org.eclipse.team.tests.cvs.core/html/00030a.html index 977ba7454..15c1cb1e2 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00030a.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00030a.html @@ -4,7 +4,7 @@ <meta NAME="since" content=""> </head><h2>Proxies</h2> <p>Since: <br> -Last Modified: $Date: 2003/11/27 22:04:58 $</p><body> +Last Modified: $Date: 2004/01/13 18:46:26 $</p><body> Using HTTP and SOCKS5 proxies. diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00032.html b/tests/org.eclipse.team.tests.cvs.core/html/00032.html index 1b9bec9b0..93f8a0edc 100644 --- a/tests/org.eclipse.team.tests.cvs.core/html/00032.html +++ b/tests/org.eclipse.team.tests.cvs.core/html/00032.html @@ -4,7 +4,7 @@ <meta NAME="since" content=""> </head><h2>General use</h2> <p>Since: <br> -Last Modified: $Date: 2003/11/27 22:04:58 $</p><body> +Last Modified: $Date: 2004/01/13 18:46:26 $</p><body> This tests the prompting and usage of the SSH2 connection method: <ul> diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00033.html b/tests/org.eclipse.team.tests.cvs.core/html/00033.html new file mode 100644 index 000000000..811c50546 --- /dev/null +++ b/tests/org.eclipse.team.tests.cvs.core/html/00033.html @@ -0,0 +1,11 @@ +<html><head><title>Annotate</title> +<LINK REL=STYLESHEET HREF=../book.css CHARSET=ISO-8859-1 TYPE=text/css> +<meta NAME="keywords" content=""> +<meta NAME="since" content=""> +</head><h2>Annotate</h2> +<p>Since: <br> +Last Modified: $Date: 2004/02/21 01:46:02 $</p><body> + +Answer comes here. + +</body></html>
\ No newline at end of file diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00034.html b/tests/org.eclipse.team.tests.cvs.core/html/00034.html new file mode 100644 index 000000000..9940287c4 --- /dev/null +++ b/tests/org.eclipse.team.tests.cvs.core/html/00034.html @@ -0,0 +1,11 @@ +<html><head><title>Show Annotation Action</title> +<LINK REL=STYLESHEET HREF=../book.css CHARSET=ISO-8859-1 TYPE=text/css> +<meta NAME="keywords" content=""> +<meta NAME="since" content=""> +</head><h2>Show Annotation Action</h2> +<p>Since: <br> +Last Modified: $Date: 2004/02/21 01:46:02 $</p><body> + +Answer comes here. + +</body></html>
\ No newline at end of file diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00035.html b/tests/org.eclipse.team.tests.cvs.core/html/00035.html new file mode 100644 index 000000000..acffdefcd --- /dev/null +++ b/tests/org.eclipse.team.tests.cvs.core/html/00035.html @@ -0,0 +1,11 @@ +<html><head><title>Label Decorations</title> +<LINK REL=STYLESHEET HREF=../book.css CHARSET=ISO-8859-1 TYPE=text/css> +<meta NAME="keywords" content=""> +<meta NAME="since" content=""> +</head><h2>Label Decorations</h2> +<p>Since: <br> +Last Modified: $Date: 2004/02/21 01:46:02 $</p><body> + +Answer comes here. + +</body></html>
\ No newline at end of file diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00036.html b/tests/org.eclipse.team.tests.cvs.core/html/00036.html new file mode 100644 index 000000000..80bda258b --- /dev/null +++ b/tests/org.eclipse.team.tests.cvs.core/html/00036.html @@ -0,0 +1,11 @@ +<html><head><title>Enablement at startup</title> +<LINK REL=STYLESHEET HREF=../book.css CHARSET=ISO-8859-1 TYPE=text/css> +<meta NAME="keywords" content=""> +<meta NAME="since" content=""> +</head><h2>Enablement at startup</h2> +<p>Since: <br> +Last Modified: $Date: 2004/02/21 01:46:02 $</p><body> + +Answer comes here. + +</body></html>
\ No newline at end of file diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00037.html b/tests/org.eclipse.team.tests.cvs.core/html/00037.html new file mode 100644 index 000000000..2bd64b88c --- /dev/null +++ b/tests/org.eclipse.team.tests.cvs.core/html/00037.html @@ -0,0 +1,11 @@ +<html><head><title>Customizations</title> +<LINK REL=STYLESHEET HREF=../book.css CHARSET=ISO-8859-1 TYPE=text/css> +<meta NAME="keywords" content=""> +<meta NAME="since" content=""> +</head><h2>Customizations</h2> +<p>Since: <br> +Last Modified: $Date: 2004/02/21 01:46:02 $</p><body> + +Answer comes here. + +</body></html>
\ No newline at end of file diff --git a/tests/org.eclipse.team.tests.cvs.core/html/00038.html b/tests/org.eclipse.team.tests.cvs.core/html/00038.html new file mode 100644 index 000000000..407b9fe6c --- /dev/null +++ b/tests/org.eclipse.team.tests.cvs.core/html/00038.html @@ -0,0 +1,11 @@ +<html><head><title>Decorations in the Synchronize pages</title> +<LINK REL=STYLESHEET HREF=../book.css CHARSET=ISO-8859-1 TYPE=text/css> +<meta NAME="keywords" content=""> +<meta NAME="since" content=""> +</head><h2>Decorations in the Synchronize pages</h2> +<p>Since: <br> +Last Modified: $Date: 2004/02/21 01:46:02 $</p><body> + +Answer comes here. + +</body></html>
\ No newline at end of file diff --git a/tests/org.eclipse.team.tests.cvs.core/launchConfigurations/One CVS Test.launch b/tests/org.eclipse.team.tests.cvs.core/launchConfigurations/One CVS Test.launch index 3d3f131ff..84bb2f295 100644 --- a/tests/org.eclipse.team.tests.cvs.core/launchConfigurations/One CVS Test.launch +++ b/tests/org.eclipse.team.tests.cvs.core/launchConfigurations/One CVS Test.launch @@ -1,17 +1,21 @@ <?xml version="1.0" encoding="UTF-8"?> <launchConfiguration type="org.eclipse.pde.ui.JunitLaunchConfig"> - <stringAttribute key="vmargs" value="-Declipse.cvs.properties=c:\eclipse\repository.properties -Declipse.cvs.testName=testFileAdditions"/> - <booleanAttribute key="askclear" value="false"/> - <booleanAttribute key="default" value="true"/> - <booleanAttribute key="clearws" value="true"/> - <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.team.tests.cvs.core"/> - <stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.jdt.debug.ui.javaSourceLocator"/> - <stringAttribute key="location0" value="C:\Eclipse\Latest-Eclipse-Drop\eclipse\runtime-test-workspace"/> - <stringAttribute - key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/> - <booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/> - <stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/> - <stringAttribute key="application" value="org.eclipse.pde.junit.runtime.coretestapplication"/> - <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.team.tests.ccvs.core.provider.IsModifiedTests"/> - <stringAttribute key="progargs" value="-os win32 -ws win32 -arch x86 -nl en_CA"/> +<booleanAttribute key="clearws" value="true"/> +<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.team.tests.ccvs.core.subscriber.CVSWorkspaceSubscriberTest"/> +<booleanAttribute key="tracing" value="false"/> +<stringAttribute key="vmargs" value="-Declipse.cvs.properties=c:\eclipse\repository.properties -Declipse.cvs.testName=testFolderConflict"/> +<booleanAttribute key="default" value="true"/> +<booleanAttribute key="clearConfig" value="true"/> +<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/> +<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/> +<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/> +<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/> +<stringAttribute key="onePluginID" value=""/> +<booleanAttribute key="useDefaultConfig" value="true"/> +<stringAttribute key="progargs" value="-os win32 -ws win32 -arch x86 -nl en_CA"/> +<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.team.tests.cvs.core"/> +<booleanAttribute key="askclear" value="false"/> +<booleanAttribute key="onePlugin" value="false"/> +<stringAttribute key="location0" value="C:\Eclipse\Latest-Eclipse-Drop\eclipse\runtime-test-workspace"/> +<stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.jdt.debug.ui.javaSourceLocator"/> </launchConfiguration> diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java index fd618b462..d80a52980 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java @@ -22,6 +22,7 @@ import org.eclipse.core.tests.harness.EclipseWorkspaceTest; import org.eclipse.swt.widgets.Display; import org.eclipse.team.core.RepositoryProvider; import org.eclipse.team.core.TeamException; +import org.eclipse.team.core.subscribers.SubscriberSyncInfoCollector; 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; @@ -31,7 +32,6 @@ 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.SyncFileChangeListener; import org.eclipse.team.internal.ccvs.ui.operations.*; -import org.eclipse.team.internal.ui.synchronize.sets.SubscriberInput; import org.eclipse.team.tests.ccvs.ui.HeadlessCVSRunnableContext; public class EclipseTest extends EclipseWorkspaceTest { @@ -766,8 +766,27 @@ public class EclipseTest extends EclipseWorkspaceTest { waitForJobCompletion(SyncFileChangeListener.getDeferredHandler().getEventHandlerJob()); } - public static void waitForSubscriberInputHandling(SubscriberInput input) { - waitForJobCompletion(input.getEventHandler().getEventHandlerJob()); + public static void waitForSubscriberInputHandling(SubscriberSyncInfoCollector input) { + input.waitForCollector(new IProgressMonitor() { + public void beginTask(String name, int totalWork) { + } + public void done() { + } + public void internalWorked(double work) { + } + public boolean isCanceled() { + return false; + } + public void setCanceled(boolean value) { + } + public void setTaskName(String name) { + } + public void subTask(String name) { + } + public void worked(int work) { + while (Display.getCurrent().readAndDispatch()) {} + } + }); } protected static void executeHeadless(CVSOperation op) throws CVSException { diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/ModuleTest.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/ModuleTest.java index d1a01d7be..7c5d3572b 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/ModuleTest.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/ModuleTest.java @@ -13,33 +13,17 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; -import junit.framework.Assert; -import junit.framework.Test; -import junit.framework.TestSuite; +import junit.framework.*; + import org.eclipse.core.internal.plugins.PluginDescriptor; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IProjectDescription; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.IWorkspaceRoot; -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.IPluginRegistry; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; +import org.eclipse.core.resources.*; +import org.eclipse.core.runtime.*; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.IRemoteSyncElement; -import org.eclipse.team.internal.ccvs.core.CVSTag; -import org.eclipse.team.internal.ccvs.core.ICVSFolder; -import org.eclipse.team.internal.ccvs.core.ICVSResource; +import org.eclipse.team.internal.ccvs.core.*; 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.Command.LocalOption; -import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; -import org.eclipse.team.internal.ccvs.core.resources.RemoteFolder; -import org.eclipse.team.internal.ccvs.core.resources.RemoteModule; +import org.eclipse.team.internal.ccvs.core.resources.*; import org.eclipse.team.tests.ccvs.core.CVSTestSetup; import org.eclipse.team.tests.ccvs.core.EclipseTest; @@ -157,10 +141,10 @@ public class ModuleTest extends EclipseTest { public void testSelfReferencingModule() throws TeamException, CoreException, IOException { uploadProject("project1"); IProject project1 = checkoutProject("project1", null); - IRemoteSyncElement tree = CVSWorkspaceRoot.getRemoteSyncTree(project1, CVSTag.DEFAULT, DEFAULT_MONITOR); - assertEquals(Path.EMPTY, CVSWorkspaceRoot.getCVSResourceFor(project1), (ICVSResource)tree.getRemote(), false, false); + ICVSRemoteResource tree = CVSWorkspaceRoot.getRemoteTree(project1, CVSTag.DEFAULT, DEFAULT_MONITOR); + assertEquals(Path.EMPTY, CVSWorkspaceRoot.getCVSResourceFor(project1), tree, false, false); RemoteModule module = getRemoteModule("project1"); - assertEquals(Path.EMPTY, (RemoteFolder)tree.getRemote(), module, false); + assertEquals(Path.EMPTY, (RemoteFolder)tree, module, false); } /* @@ -173,16 +157,16 @@ public class ModuleTest extends EclipseTest { public void testFlattenedStructure() throws TeamException, CoreException, IOException { IProject docs = checkoutProject("docs", null); - IRemoteSyncElement tree = CVSWorkspaceRoot.getRemoteSyncTree(docs, CVSTag.DEFAULT, DEFAULT_MONITOR); - assertEquals(Path.EMPTY, CVSWorkspaceRoot.getCVSResourceFor(docs), (ICVSResource)tree.getRemote(), false, false); + ICVSRemoteResource tree = CVSWorkspaceRoot.getRemoteTree(docs, CVSTag.DEFAULT, DEFAULT_MONITOR); + assertEquals(Path.EMPTY, CVSWorkspaceRoot.getCVSResourceFor(docs), tree, false, false); RemoteModule module = getRemoteModule("docs"); - assertEquals(Path.EMPTY, (RemoteFolder)tree.getRemote(), module, false); + assertEquals(Path.EMPTY, (RemoteFolder)tree, module, false); IProject macros = checkoutProject("macros", null); - tree = CVSWorkspaceRoot.getRemoteSyncTree(macros, CVSTag.DEFAULT, DEFAULT_MONITOR); - assertEquals(Path.EMPTY, CVSWorkspaceRoot.getCVSResourceFor(macros), (ICVSResource)tree.getRemote(), false, false); + tree = CVSWorkspaceRoot.getRemoteTree(macros, CVSTag.DEFAULT, DEFAULT_MONITOR); + assertEquals(Path.EMPTY, CVSWorkspaceRoot.getCVSResourceFor(macros), tree, false, false); module = getRemoteModule("macros"); - assertEquals(Path.EMPTY, (RemoteFolder)tree.getRemote(), module, false); + assertEquals(Path.EMPTY, (RemoteFolder)tree, module, false); } @@ -197,18 +181,18 @@ public class ModuleTest extends EclipseTest { public void testIncludeAndExcludeDocs() throws TeamException, CoreException, IOException { uploadProject("project2"); IProject project2 = checkoutProject("project2", null); - IRemoteSyncElement tree = CVSWorkspaceRoot.getRemoteSyncTree(project2, CVSTag.DEFAULT, DEFAULT_MONITOR); - assertEquals(Path.EMPTY, CVSWorkspaceRoot.getCVSResourceFor(project2), (ICVSResource)tree.getRemote(), false, false); + ICVSRemoteResource tree = CVSWorkspaceRoot.getRemoteTree(project2, CVSTag.DEFAULT, DEFAULT_MONITOR); + assertEquals(Path.EMPTY, CVSWorkspaceRoot.getCVSResourceFor(project2), tree, false, false); RemoteModule module = getRemoteModule("project2"); - assertEquals(Path.EMPTY, (RemoteFolder)tree.getRemote(), module, false); + assertEquals(Path.EMPTY, (RemoteFolder)tree, module, false); project2 = checkoutProject("project2-only", null); - tree = CVSWorkspaceRoot.getRemoteSyncTree(project2, CVSTag.DEFAULT, DEFAULT_MONITOR); - assertEquals(Path.EMPTY, CVSWorkspaceRoot.getCVSResourceFor(project2), (ICVSResource)tree.getRemote(), false, false); + tree = CVSWorkspaceRoot.getRemoteTree(project2, CVSTag.DEFAULT, DEFAULT_MONITOR); + assertEquals(Path.EMPTY, CVSWorkspaceRoot.getCVSResourceFor(project2), tree, false, false); module = getRemoteModule("project2-only"); - assertEquals(Path.EMPTY, (RemoteFolder)tree.getRemote(), module, false); + assertEquals(Path.EMPTY, (RemoteFolder)tree, module, false); } @@ -223,15 +207,15 @@ public class ModuleTest extends EclipseTest { public void testAliasForFiles() throws TeamException, CoreException, IOException { uploadProject("project3"); IProject project3 = checkoutProject("project3-sub", null); - IRemoteSyncElement tree = CVSWorkspaceRoot.getRemoteSyncTree(project3, CVSTag.DEFAULT, DEFAULT_MONITOR); + ICVSRemoteResource tree = CVSWorkspaceRoot.getRemoteTree(project3, CVSTag.DEFAULT, DEFAULT_MONITOR); // assertEquals("Local does not match remote", Session.getManagedResource(project3), (ICVSResource)tree.getRemote(), false, false); project3 = checkoutProject("project3-src", null); - tree = CVSWorkspaceRoot.getRemoteSyncTree(project3, CVSTag.DEFAULT, DEFAULT_MONITOR); + tree = CVSWorkspaceRoot.getRemoteTree(project3, CVSTag.DEFAULT, DEFAULT_MONITOR); // assertEquals("Local does not match remote", Session.getManagedResource(project3), (ICVSResource)tree.getRemote(), false, false); project3 = checkoutProject("project3-src_file", null); - tree = CVSWorkspaceRoot.getRemoteSyncTree(project3, CVSTag.DEFAULT, DEFAULT_MONITOR); + tree = CVSWorkspaceRoot.getRemoteTree(project3, CVSTag.DEFAULT, DEFAULT_MONITOR); // assertEquals("Local does not match remote", Session.getManagedResource(project3), (ICVSResource)tree.getRemote(), false, false); } @@ -246,15 +230,15 @@ public class ModuleTest extends EclipseTest { public void testAliases() throws TeamException, CoreException, IOException { uploadProject("project7"); IProject project7 = checkoutProject("project7-common", null); - IRemoteSyncElement tree = CVSWorkspaceRoot.getRemoteSyncTree(project7, CVSTag.DEFAULT, DEFAULT_MONITOR); + ICVSRemoteResource tree = CVSWorkspaceRoot.getRemoteTree(project7, CVSTag.DEFAULT, DEFAULT_MONITOR); // assertEquals("Local does not match remote", Session.getManagedResource(project7), (ICVSResource)tree.getRemote(), false, false); project7 = checkoutProject("project7-pc", null); - tree = CVSWorkspaceRoot.getRemoteSyncTree(project7, CVSTag.DEFAULT, DEFAULT_MONITOR); + tree = CVSWorkspaceRoot.getRemoteTree(project7, CVSTag.DEFAULT, DEFAULT_MONITOR); // assertEquals("Local does not match remote", Session.getManagedResource(project7), (ICVSResource)tree.getRemote(), false, false); project7 = checkoutProject("project7-linux", null); - tree = CVSWorkspaceRoot.getRemoteSyncTree(project7, CVSTag.DEFAULT, DEFAULT_MONITOR); + tree = CVSWorkspaceRoot.getRemoteTree(project7, CVSTag.DEFAULT, DEFAULT_MONITOR); // assertEquals("Local does not match remote", Session.getManagedResource(project7), (ICVSResource)tree.getRemote(), false, false); } diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/RemoteResourceTest.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/RemoteResourceTest.java index 6e32a158a..eef4fa51e 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/RemoteResourceTest.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/RemoteResourceTest.java @@ -15,28 +15,13 @@ import java.lang.reflect.InvocationTargetException; import junit.framework.Test; -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.*; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Path; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.IRemoteResource; -import org.eclipse.team.core.sync.IRemoteSyncElement; -import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.CVSTag; -import org.eclipse.team.internal.ccvs.core.CVSTeamProvider; -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.ICVSResource; -import org.eclipse.team.internal.ccvs.core.ILogEntry; -import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; -import org.eclipse.team.internal.ccvs.core.resources.RemoteFolder; -import org.eclipse.team.internal.ccvs.core.resources.RemoteFolderTree; -import org.eclipse.team.internal.ccvs.core.resources.RemoteFolderTreeBuilder; +import org.eclipse.team.core.synchronize.IResourceVariant; +import org.eclipse.team.internal.ccvs.core.*; +import org.eclipse.team.internal.ccvs.core.resources.*; import org.eclipse.team.internal.ccvs.ui.operations.CheckoutToRemoteFolderOperation; import org.eclipse.team.tests.ccvs.core.CVSTestSetup; import org.eclipse.team.tests.ccvs.core.EclipseTest; @@ -60,7 +45,7 @@ public class RemoteResourceTest extends EclipseTest { } protected void getMembers(ICVSRemoteFolder folder, boolean deep) throws TeamException { - IRemoteResource[] children = folder.members(DEFAULT_MONITOR); + ICVSRemoteResource[] children = folder.members(DEFAULT_MONITOR); if (deep) { for (int i=0;i<children.length;i++) { if (children[i].isContainer()) @@ -192,13 +177,13 @@ public class RemoteResourceTest extends EclipseTest { getProvider(project).checkin(new IResource[] {project}, IResource.DEPTH_INFINITE, DEFAULT_MONITOR); // Fetch the remote tree for the version - IRemoteSyncElement tree = CVSWorkspaceRoot.getRemoteSyncTree(project, v1Tag, DEFAULT_MONITOR); + ICVSRemoteResource tree = CVSWorkspaceRoot.getRemoteTree(project, v1Tag, DEFAULT_MONITOR); // Check out the project version project = checkoutCopy(project, v1Tag); // Compare the two - assertEquals(Path.EMPTY, (ICVSResource)tree.getRemote(), (ICVSResource)CVSWorkspaceRoot.getCVSResourceFor(project), false, false); + assertEquals(Path.EMPTY, tree, (ICVSResource)CVSWorkspaceRoot.getCVSResourceFor(project), false, false); } /* @@ -212,8 +197,8 @@ public class RemoteResourceTest extends EclipseTest { setContentsAndEnsureModified(file, ""); commitResources(project, new String[] {"file.txt"}); - ICVSRemoteResource remote = CVSWorkspaceRoot.getRemoteResourceFor(file); - InputStream in = remote.getContents(DEFAULT_MONITOR); + IResourceVariant remote = (IResourceVariant)CVSWorkspaceRoot.getRemoteResourceFor(file); + InputStream in = remote.getStorage(DEFAULT_MONITOR).getContents(); int count = 0; while(in.read() != -1) { count++; @@ -353,8 +338,8 @@ public class RemoteResourceTest extends EclipseTest { setContentsAndEnsureModified(project.getFile("file1.txt"), contents); commitProject(project); project.getFile("file1.txt").delete(false, null); - ICVSRemoteFile remote = (ICVSRemoteFile)CVSWorkspaceRoot.getRemoteResourceFor(project.getFile("file1.txt")); - String fetchedContents = asString(remote.getBufferedStorage(DEFAULT_MONITOR).getContents()); + IResourceVariant remote = (IResourceVariant)CVSWorkspaceRoot.getRemoteResourceFor(project.getFile("file1.txt")); + String fetchedContents = asString(remote.getStorage(DEFAULT_MONITOR).getContents()); assertEquals("Contents do not match", contents, fetchedContents); } diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/AllTestsTeamSubscriber.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/AllTestsTeamSubscriber.java index 86d9809b1..4368eb558 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/AllTestsTeamSubscriber.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/AllTestsTeamSubscriber.java @@ -30,6 +30,7 @@ public class AllTestsTeamSubscriber extends EclipseTest { TestSuite suite = new TestSuite(); suite.addTest(CVSMergeSubscriberTest.suite()); suite.addTest(CVSWorkspaceSubscriberTest.suite()); + suite.addTest(CVSCompareSubscriberTest.suite()); suite.addTest(SyncSetTests.suite()); CVSSyncSubscriberTest.setSyncSource(new SynchronizeViewTestAdapter()); return new CVSTestSetup(suite); diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSCompareSubscriberTest.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSCompareSubscriberTest.java new file mode 100644 index 000000000..90d9d4108 --- /dev/null +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSCompareSubscriberTest.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * 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.tests.ccvs.core.subscriber; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.team.core.synchronize.SyncInfo; +import org.eclipse.team.internal.ccvs.core.*; +import org.eclipse.team.tests.ccvs.core.CVSTestSetup; + +/** + * Tests the CVSMergeSubscriber + */ +public class CVSCompareSubscriberTest extends CVSSyncSubscriberTest { + + public static Test suite() { + String testName = System.getProperty("eclipse.cvs.testName"); + if (testName == null) { + TestSuite suite = new TestSuite(CVSCompareSubscriberTest.class); + return new CVSTestSetup(suite); + } else { + return new CVSTestSetup(new CVSCompareSubscriberTest(testName)); + } + } + + public CVSCompareSubscriberTest() { + super(); + } + + public CVSCompareSubscriberTest(String name) { + super(name); + } + + /** + * Test the basic changes that can occur when comparing the local workspace to a remote + * lineup. + */ + public void testStandardChanges() throws InvocationTargetException, InterruptedException, CVSException, CoreException, IOException { + // Create a test project + IProject project = createProject("testCompareChanges", new String[]{"file1.txt", "file2.txt", "folder1/", "folder1/a.txt", "folder1/b.txt", "folder2/", "folder2/deleted.txt"}); + // Checkout and branch a copy + CVSTag tag = new CVSTag("v1", CVSTag.VERSION); + tagProject(project, tag, true); + // Modify the workspace + addResources(project, new String[]{"addition.txt", "folderAddition/", "folderAddition/new.txt"}, true); + deleteResources(project, new String[]{"folder1/a.txt"}, true); + deleteResources(project, new String[] {"folder2/"}, true); + // modify file1 - make two revisions + appendText(project.getFile("file1.txt"), "Appended text 1", false); + commitProject(project); + appendText(project.getFile("file1.txt"), "Appended text 2", false); + commitProject(project); + // modify file2 in both branch and head and ensure it's merged properly + appendText(project.getFile("file2.txt"), "appened text", false); + commitProject(project); + // create a merge subscriber + CVSCompareSubscriber subscriber = getSyncInfoSource().createCompareSubscriber(project, tag); + // check the sync states + assertSyncEquals("testIncomingChanges", subscriber, project, + new String[]{ + "file1.txt", + "file2.txt", + "folder1/", + "folder1/b.txt", + "folder1/a.txt", + "addition.txt", + "folderAddition/", + "folderAddition/new.txt", + "folder2/", + "folder2/deleted.txt"}, true, + new int[]{ + SyncInfo.CHANGE, + SyncInfo.CHANGE, + SyncInfo.IN_SYNC, + SyncInfo.IN_SYNC, + SyncInfo.ADDITION, + SyncInfo.DELETION, + SyncInfo.IN_SYNC, + SyncInfo.DELETION, + SyncInfo.IN_SYNC, + SyncInfo.ADDITION}); + } + + /* (non-Javadoc) + * @see junit.framework.TestCase#tearDown() + */ + protected void tearDown() throws Exception { + getSyncInfoSource().tearDown(); + super.tearDown(); + } +} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSMergeSubscriberTest.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSMergeSubscriberTest.java index 729094d9e..ab4ff8325 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSMergeSubscriberTest.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSMergeSubscriberTest.java @@ -21,14 +21,11 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.team.core.RepositoryProvider; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.core.subscribers.TeamSubscriber; -import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.CVSMergeSubscriber; -import org.eclipse.team.internal.ccvs.core.CVSTag; +import org.eclipse.team.core.subscribers.*; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.core.client.Command; import org.eclipse.team.tests.ccvs.core.CVSTestSetup; -import org.eclipse.team.ui.synchronize.actions.SyncInfoSet; /** @@ -69,7 +66,7 @@ public class CVSMergeSubscriberTest extends CVSSyncSubscriberTest { mergeResources(subscriber, infos, allowOverwrite); } - private void mergeResources(TeamSubscriber subscriber, SyncInfo[] infos, boolean allowOverwrite) throws TeamException, InvocationTargetException, InterruptedException { + private void mergeResources(Subscriber subscriber, SyncInfo[] infos, boolean allowOverwrite) throws TeamException, InvocationTargetException, InterruptedException { TestMergeUpdateAction action = new TestMergeUpdateAction(allowOverwrite); action.getRunnable(new SyncInfoSet(infos)).run(DEFAULT_MONITOR); } diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSSyncSubscriberTest.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSSyncSubscriberTest.java index c65d34f9b..66caa4549 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSSyncSubscriberTest.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSSyncSubscriberTest.java @@ -11,37 +11,27 @@ package org.eclipse.team.tests.ccvs.core.subscriber; import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import junit.framework.AssertionFailedError; -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceVisitor; +import org.eclipse.core.resources.*; import org.eclipse.core.runtime.CoreException; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.ITeamResourceChangeListener; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.core.subscribers.TeamDelta; -import org.eclipse.team.core.subscribers.TeamSubscriber; -import org.eclipse.team.core.sync.RemoteSyncElement; +import org.eclipse.team.core.subscribers.*; +import org.eclipse.team.core.synchronize.SyncInfo; +import org.eclipse.team.core.synchronize.SyncInfoSet; import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin; import org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber; import org.eclipse.team.tests.ccvs.core.EclipseTest; import org.eclipse.team.tests.ccvs.ui.SynchronizeViewTestAdapter; -import org.eclipse.team.ui.synchronize.actions.SyncInfoSet; /** * Provides test methods common to CVS sync subscribers */ public abstract class CVSSyncSubscriberTest extends EclipseTest { - private ITeamResourceChangeListener listener; + private ISubscriberChangeListener listener; private List accumulatedTeamDeltas = new ArrayList(); private static SyncInfoSource source = new SynchronizeViewTestAdapter(); @@ -57,8 +47,8 @@ public abstract class CVSSyncSubscriberTest extends EclipseTest { source = newSource; } - protected TeamSubscriber getWorkspaceSubscriber() throws TeamException { - TeamSubscriber subscriber = CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber(); + protected Subscriber getWorkspaceSubscriber() throws TeamException { + Subscriber subscriber = CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber(); if (subscriber == null) fail("The CVS sync subsciber is not registered"); return subscriber; } @@ -68,7 +58,7 @@ public abstract class CVSSyncSubscriberTest extends EclipseTest { return source; } - protected void refresh(TeamSubscriber subscriber, IResource resource) throws TeamException { + protected void refresh(Subscriber subscriber, IResource resource) throws TeamException { getSyncInfoSource().refresh(subscriber, resource); } @@ -76,7 +66,7 @@ public abstract class CVSSyncSubscriberTest extends EclipseTest { * Assert that the specified resources in the subscriber have the specified sync kind * Ignore conflict types if they are not specified in the assert statement */ - protected void assertSyncEquals(String message, TeamSubscriber subscriber, IContainer root, String[] resourcePaths, boolean refresh, int[] syncKinds) throws CoreException, TeamException { + protected void assertSyncEquals(String message, Subscriber subscriber, IContainer root, String[] resourcePaths, boolean refresh, int[] syncKinds) throws CoreException, TeamException { assertTrue(resourcePaths.length == syncKinds.length); if (refresh) refresh(subscriber, root); IResource[] resources = getResources(root, resourcePaths); @@ -86,7 +76,7 @@ public abstract class CVSSyncSubscriberTest extends EclipseTest { } - protected void assertSyncEquals(String message, TeamSubscriber subscriber, IResource resource, int syncKind) throws TeamException { + protected void assertSyncEquals(String message, Subscriber subscriber, IResource resource, int syncKind) throws TeamException { int conflictTypeMask = 0x0F; // ignore manual and auto merge sync types for now. SyncInfo info = getSyncInfo(subscriber, resource); int kind; @@ -97,11 +87,11 @@ public abstract class CVSSyncSubscriberTest extends EclipseTest { kind = info.getKind() & conflictTypeMask; } assertTrue(message + ": improper sync state for " + resource + " expected " + - RemoteSyncElement.kindToString(kindOther) + " but was " + - RemoteSyncElement.kindToString(kind), kind == kindOther); + SyncInfo.kindToString(kindOther) + " but was " + + SyncInfo.kindToString(kind), kind == kindOther); } - protected SyncInfo getSyncInfo(TeamSubscriber subscriber, IResource resource) throws TeamException { + protected SyncInfo getSyncInfo(Subscriber subscriber, IResource resource) throws TeamException { return getSyncInfoSource().getSyncInfo(subscriber, resource); } @@ -109,13 +99,13 @@ public abstract class CVSSyncSubscriberTest extends EclipseTest { * @param changes * @param resources */ - protected void assertSyncChangesMatch(TeamDelta[] changes, IResource[] resources) { + protected void assertSyncChangesMatch(ISubscriberChangeEvent[] changes, IResource[] resources) { // First, ensure that all the resources appear in the delta for (int i = 0; i < resources.length; i++) { IResource resource = resources[i]; boolean found = false; for (int j = 0; j < changes.length; j++) { - TeamDelta delta = changes[j]; + ISubscriberChangeEvent delta = changes[j]; if (delta.getResource().equals(resource)) { found = true; break; @@ -203,14 +193,14 @@ public abstract class CVSSyncSubscriberTest extends EclipseTest { return (IResource[]) affected.toArray(new IResource[affected.size()]); } - protected TeamDelta[] deregisterSubscriberListener(TeamSubscriber subscriber) throws TeamException { + protected ISubscriberChangeEvent[] deregisterSubscriberListener(Subscriber subscriber) throws TeamException { subscriber.removeListener(listener); - return (TeamDelta[]) accumulatedTeamDeltas.toArray(new TeamDelta[accumulatedTeamDeltas.size()]); + return (ISubscriberChangeEvent[]) accumulatedTeamDeltas.toArray(new SubscriberChangeEvent[accumulatedTeamDeltas.size()]); } - protected ITeamResourceChangeListener registerSubscriberListener(TeamSubscriber subscriber) throws TeamException { - listener = new ITeamResourceChangeListener() { - public void teamResourceChanged(TeamDelta[] deltas) { + protected ISubscriberChangeListener registerSubscriberListener(Subscriber subscriber) throws TeamException { + listener = new ISubscriberChangeListener() { + public void subscriberResourceChanged(ISubscriberChangeEvent[] deltas) { accumulatedTeamDeltas.addAll(Arrays.asList(deltas)); } }; @@ -219,7 +209,7 @@ public abstract class CVSSyncSubscriberTest extends EclipseTest { return listener; } - protected SyncInfo[] createSyncInfos(TeamSubscriber subscriber, IResource[] resources) throws TeamException { + protected SyncInfo[] createSyncInfos(Subscriber subscriber, IResource[] resources) throws TeamException { SyncInfo[] result = new SyncInfo[resources.length]; for (int i = 0; i < resources.length; i++) { IResource resource = resources[i]; @@ -228,7 +218,7 @@ public abstract class CVSSyncSubscriberTest extends EclipseTest { return result; } - protected void assertProjectRemoved(TeamSubscriber subscriber, IProject project) throws TeamException { + protected void assertProjectRemoved(Subscriber subscriber, IProject project) throws TeamException { getSyncInfoSource().assertProjectRemoved(subscriber, project); } diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSWorkspaceSubscriberTest.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSWorkspaceSubscriberTest.java index 64af9a52d..221a261c8 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSWorkspaceSubscriberTest.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSWorkspaceSubscriberTest.java @@ -24,6 +24,7 @@ import org.eclipse.core.runtime.Path; import org.eclipse.team.core.RepositoryProvider; import org.eclipse.team.core.TeamException; import org.eclipse.team.core.subscribers.*; +import org.eclipse.team.core.synchronize.*; import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.core.client.Command; import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; @@ -31,7 +32,6 @@ import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo; import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; import org.eclipse.team.internal.ccvs.ui.subscriber.CVSSubscriberAction; import org.eclipse.team.tests.ccvs.core.CVSTestSetup; -import org.eclipse.team.ui.synchronize.actions.SyncInfoSet; /** * This class tests the CVSWorkspaceSubscriber @@ -153,7 +153,7 @@ public class CVSWorkspaceSubscriberTest extends CVSSyncSubscriberTest { registerSubscriberListener(); super.addResources(resources); - TeamDelta[] changes = deregisterSubscriberListener(); + ISubscriberChangeEvent[] changes = deregisterSubscriberListener(); assertSyncChangesMatch(changes, (IResource[]) affected.toArray(new IResource[affected.size()])); for (int i = 0; i < resources.length; i++) { IResource resource = resources[i]; @@ -178,7 +178,7 @@ public class CVSWorkspaceSubscriberTest extends CVSSyncSubscriberTest { IResource[] affected = collect(resources, new ResourceCondition(), IResource.DEPTH_INFINITE); registerSubscriberListener(); super.deleteResources(resources); - TeamDelta[] changes = deregisterSubscriberListener(); + ISubscriberChangeEvent[] changes = deregisterSubscriberListener(); assertSyncChangesMatch(changes, affected); for (int i = 0; i < resources.length; i++) { IResource resource = resources[i]; @@ -191,7 +191,7 @@ public class CVSWorkspaceSubscriberTest extends CVSSyncSubscriberTest { } } - private TeamDelta[] deregisterSubscriberListener() throws TeamException { + private ISubscriberChangeEvent[] deregisterSubscriberListener() throws TeamException { return deregisterSubscriberListener(getSubscriber()); } @@ -207,7 +207,7 @@ public class CVSWorkspaceSubscriberTest extends CVSSyncSubscriberTest { }, IResource.DEPTH_INFINITE); registerSubscriberListener(); super.commitResources(resources, depth); - TeamDelta[] changes = deregisterSubscriberListener(); + ISubscriberChangeEvent[] changes = deregisterSubscriberListener(); assertSyncChangesMatch(changes, affected); for (int i = 0; i < resources.length; i++) { IResource resource = resources[i]; @@ -228,7 +228,7 @@ public class CVSWorkspaceSubscriberTest extends CVSSyncSubscriberTest { }, IResource.DEPTH_INFINITE); registerSubscriberListener(); super.unmanageResources(resources); - TeamDelta[] changes = deregisterSubscriberListener(); + ISubscriberChangeEvent[] changes = deregisterSubscriberListener(); assertSyncChangesMatch(changes, affected); for (int i = 0; i < resources.length; i++) { IResource resource = resources[i]; @@ -915,48 +915,6 @@ public class CVSWorkspaceSubscriberTest extends CVSSyncSubscriberTest { SyncInfo.IN_SYNC, SyncInfo.IN_SYNC}); } - - /* - * Test changes using a granularity of contents - */ - public void testGranularityContents() throws TeamException, CoreException, IOException { - // Create a test project (which commits it as well) - IProject project = createProject(new String[] { "file1.txt", "folder1/", "folder1/a.txt", "folder1/b.txt"}); - - // Checkout a copy and make some modifications - IProject copy = checkoutCopy(project, "-copy"); - appendText(copy.getFile("file1.txt"), "same text", false); - setContentsAndEnsureModified(copy.getFile("folder1/a.txt"), " unique text"); // whitespace difference - commitProject(copy); - - // Make the same modifications to the original - appendText(project.getFile("file1.txt"), "same text", false); - setContentsAndEnsureModified(project.getFile("folder1/a.txt"), "unique text"); // whitespace difference - - // Get the sync tree for the project - String oldId = getSubscriber().getCurrentComparisonCriteria().getId(); - try { - getSubscriber().setCurrentComparisonCriteria(ContentComparisonCriteria.ID_DONTIGNORE_WS); - assertSyncEquals("testGranularityContents", project, - new String[] { "file1.txt", "folder1/", "folder1/a.txt"}, - true, new int[] { - SyncInfo.IN_SYNC, - SyncInfo.IN_SYNC, - SyncInfo.CONFLICTING | SyncInfo.CHANGE }); - getSubscriber().setCurrentComparisonCriteria(ContentComparisonCriteria.ID_IGNORE_WS); - // TODO: Should not need to reset after a comparison criteria change (bug 46678) - getSyncInfoSource().reset(getSubscriber()); - assertSyncEquals("testGranularityContents", project, - new String[] { "file1.txt", "folder1/", "folder1/a.txt"}, - true, new int[] { - SyncInfo.IN_SYNC, - SyncInfo.IN_SYNC, - SyncInfo.IN_SYNC }); - } finally { - getSubscriber().setCurrentComparisonCriteria(oldId); - } - - } public void testSyncOnBranch() throws TeamException, CoreException, IOException { diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/SyncInfoSource.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/SyncInfoSource.java index e55253553..6eddc52dc 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/SyncInfoSource.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/SyncInfoSource.java @@ -10,9 +10,7 @@ *******************************************************************************/ package org.eclipse.team.tests.ccvs.core.subscriber; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; +import java.util.*; import junit.framework.AssertionFailedError; @@ -21,10 +19,9 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.core.subscribers.TeamSubscriber; -import org.eclipse.team.internal.ccvs.core.CVSMergeSubscriber; -import org.eclipse.team.internal.ccvs.core.CVSTag; +import org.eclipse.team.core.subscribers.Subscriber; +import org.eclipse.team.core.synchronize.SyncInfo; +import org.eclipse.team.internal.ccvs.core.*; /** * This class acts as the source for the sync info used by the subscriber tests. @@ -35,6 +32,7 @@ public class SyncInfoSource { protected static IProgressMonitor DEFAULT_MONITOR = new NullProgressMonitor(); protected List mergeSubscribers = new ArrayList(); + protected List compareSubscribers = new ArrayList(); public CVSMergeSubscriber createMergeSubscriber(IProject project, CVSTag root, CVSTag branch) { CVSMergeSubscriber subscriber = new CVSMergeSubscriber(new IResource[] { project }, root, branch); @@ -42,21 +40,27 @@ public class SyncInfoSource { return subscriber; } + public CVSCompareSubscriber createCompareSubscriber(IProject project, CVSTag tag) { + CVSCompareSubscriber subscriber = new CVSCompareSubscriber(new IResource[] { project }, tag); + compareSubscribers.add(subscriber); + return subscriber; + } + /** * Return the sync info for the given subscriber for the given resource. */ - public SyncInfo getSyncInfo(TeamSubscriber subscriber, IResource resource) throws TeamException { - return subscriber.getSyncInfo(resource, DEFAULT_MONITOR = new NullProgressMonitor()); + public SyncInfo getSyncInfo(Subscriber subscriber, IResource resource) throws TeamException { + return subscriber.getSyncInfo(resource); } /** * Refresh the subscriber for the given resource */ - public void refresh(TeamSubscriber subscriber, IResource resource) throws TeamException { + public void refresh(Subscriber subscriber, IResource resource) throws TeamException { subscriber.refresh(new IResource[] { resource}, IResource.DEPTH_INFINITE, DEFAULT_MONITOR); } - protected void assertProjectRemoved(TeamSubscriber subscriber, IProject project) throws TeamException { + protected void assertProjectRemoved(Subscriber subscriber, IProject project) throws TeamException { IResource[] roots = subscriber.roots(); for (int i = 0; i < roots.length; i++) { IResource resource = roots[i]; @@ -76,7 +80,7 @@ public class SyncInfoSource { /** * Recalculate a sync info from scratch */ - public void reset(TeamSubscriber subscriber) throws TeamException { + public void reset(Subscriber subscriber) throws TeamException { // Do nothing } diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/SyncSetTests.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/SyncSetTests.java index 7878f29cb..039ddcedd 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/SyncSetTests.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/SyncSetTests.java @@ -13,16 +13,13 @@ package org.eclipse.team.tests.ccvs.core.subscriber; import junit.framework.Test; import junit.framework.TestSuite; +import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.IJobChangeEvent; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.core.runtime.jobs.JobChangeAdapter; +import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.jobs.*; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.internal.ui.synchronize.sets.SyncSet; +import org.eclipse.team.core.synchronize.SyncInfo; +import org.eclipse.team.internal.core.subscribers.SubscriberSyncInfoSet; import org.eclipse.team.tests.ccvs.core.CVSTestSetup; @@ -47,11 +44,11 @@ public class SyncSetTests extends CVSSyncSubscriberTest { } class TestSyncInfo extends SyncInfo { - protected int calculateKind(IProgressMonitor progress) throws TeamException { + protected int calculateKind() throws TeamException { return 0; } public TestSyncInfo() throws TeamException { - super(ResourcesPlugin.getWorkspace().getRoot(), null, null, null, null); + super(ResourcesPlugin.getWorkspace().getRoot(), null, null, null); } } @@ -60,7 +57,7 @@ public class SyncSetTests extends CVSSyncSubscriberTest { * that doesn't validate the actual contents of the sync set. */ public void testConcurrentAccessToSyncSet() throws Throwable { - final SyncSet set = new SyncSet(); + final SubscriberSyncInfoSet set = new SubscriberSyncInfoSet(null); final boolean[] done = {false}; final IStatus[] error = {null}; @@ -70,9 +67,9 @@ public class SyncSetTests extends CVSSyncSubscriberTest { while(! done[0]) { try { set.add(new TestSyncInfo()); - set.getOutOfSyncDescendants(ResourcesPlugin.getWorkspace().getRoot()); + set.getSyncInfos(ResourcesPlugin.getWorkspace().getRoot(), IResource.DEPTH_INFINITE); set.getSyncInfo(ResourcesPlugin.getWorkspace().getRoot()); - set.allMembers(); + set.getSyncInfos(); } catch (Exception e) { error[0] = new Status(IStatus.ERROR, "this", 1, "", e); return error[0]; @@ -95,11 +92,11 @@ public class SyncSetTests extends CVSSyncSubscriberTest { for(int i = 0; i < 10000; i++) { set.add(new TestSyncInfo()); - set.getOutOfSyncDescendants(ResourcesPlugin.getWorkspace().getRoot()); + set.getSyncInfos(ResourcesPlugin.getWorkspace().getRoot(), IResource.DEPTH_INFINITE); set.getSyncInfo(ResourcesPlugin.getWorkspace().getRoot()); - set.allMembers(); + set.getSyncInfos(); set.members(ResourcesPlugin.getWorkspace().getRoot()); - set.reset(); + set.clear(); } done[0] = true; if(error[0] != null) { diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestCommitAction.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestCommitAction.java index 692a1fd81..48ff6566e 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestCommitAction.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestCommitAction.java @@ -12,9 +12,9 @@ package org.eclipse.team.tests.ccvs.core.subscriber; import org.eclipse.core.resources.IResource; import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.team.core.synchronize.SyncInfoSet; import org.eclipse.team.internal.ccvs.ui.repo.RepositoryManager; import org.eclipse.team.internal.ccvs.ui.subscriber.SubscriberCommitAction; -import org.eclipse.team.ui.synchronize.actions.SyncInfoSet; class TestCommitAction extends SubscriberCommitAction { diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestMarkAsMergedAction.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestMarkAsMergedAction.java index deaa3a8ae..35d6e4212 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestMarkAsMergedAction.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestMarkAsMergedAction.java @@ -11,8 +11,8 @@ package org.eclipse.team.tests.ccvs.core.subscriber; import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.team.core.synchronize.SyncInfoSet; import org.eclipse.team.internal.ccvs.ui.subscriber.SubscriberConfirmMergedAction; -import org.eclipse.team.ui.synchronize.actions.SyncInfoSet; class TestMarkAsMergedAction extends SubscriberConfirmMergedAction { diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestMergeUpdateAction.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestMergeUpdateAction.java index 8e40682d4..b6c5735ff 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestMergeUpdateAction.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestMergeUpdateAction.java @@ -12,9 +12,9 @@ package org.eclipse.team.tests.ccvs.core.subscriber; import org.eclipse.core.resources.IResource; import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.team.core.synchronize.SyncInfoSet; import org.eclipse.team.internal.ccvs.ui.subscriber.MergeUpdateAction; import org.eclipse.team.tests.ccvs.core.EclipseTest; -import org.eclipse.team.ui.synchronize.actions.SyncInfoSet; class TestMergeUpdateAction extends MergeUpdateAction { diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestOverrideAndCommit.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestOverrideAndCommit.java index 7f4b6f437..21a7817f6 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestOverrideAndCommit.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestOverrideAndCommit.java @@ -11,9 +11,9 @@ package org.eclipse.team.tests.ccvs.core.subscriber; import org.eclipse.core.resources.IResource; +import org.eclipse.team.core.synchronize.SyncInfoSet; import org.eclipse.team.internal.ccvs.ui.repo.RepositoryManager; import org.eclipse.team.internal.ccvs.ui.subscriber.OverrideAndCommitAction; -import org.eclipse.team.ui.synchronize.actions.SyncInfoSet; public class TestOverrideAndCommit extends OverrideAndCommitAction { diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestOverrideAndUpdate.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestOverrideAndUpdate.java index f31d4c36f..155c1166e 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestOverrideAndUpdate.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestOverrideAndUpdate.java @@ -1,7 +1,7 @@ package org.eclipse.team.tests.ccvs.core.subscriber; +import org.eclipse.team.core.synchronize.SyncInfoSet; import org.eclipse.team.internal.ccvs.ui.subscriber.OverrideAndUpdateAction; -import org.eclipse.team.ui.synchronize.actions.SyncInfoSet; public class TestOverrideAndUpdate extends OverrideAndUpdateAction { diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestUpdateAction.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestUpdateAction.java index 1007996ec..1bc36c774 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestUpdateAction.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/TestUpdateAction.java @@ -11,9 +11,9 @@ package org.eclipse.team.tests.ccvs.core.subscriber; import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.team.core.synchronize.SyncInfoSet; import org.eclipse.team.internal.ccvs.ui.subscriber.WorkspaceUpdateAction; import org.eclipse.team.tests.ccvs.core.EclipseTest; -import org.eclipse.team.ui.synchronize.actions.SyncInfoSet; class TestUpdateAction extends WorkspaceUpdateAction { diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/HeadlessCVSRunnableContext.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/HeadlessCVSRunnableContext.java index b36f43c8b..da2804248 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/HeadlessCVSRunnableContext.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/HeadlessCVSRunnableContext.java @@ -17,10 +17,10 @@ import org.eclipse.core.runtime.jobs.IJobChangeListener; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.swt.widgets.Shell; -import org.eclipse.team.internal.ccvs.ui.operations.CVSNonblockingRunnableContext; -import org.eclipse.team.internal.ccvs.ui.operations.ICVSRunnableContext; +import org.eclipse.team.internal.ui.actions.ITeamRunnableContext; +import org.eclipse.team.internal.ui.actions.JobRunnableContext; -public class HeadlessCVSRunnableContext implements ICVSRunnableContext { +public class HeadlessCVSRunnableContext implements ITeamRunnableContext { private boolean background; private IJobChangeListener listener; @@ -34,7 +34,7 @@ public class HeadlessCVSRunnableContext implements ICVSRunnableContext { } /* (non-Javadoc) - * @see org.eclipse.team.internal.ccvs.ui.operations.ICVSRunnableContext#run(java.lang.String, org.eclipse.core.runtime.jobs.ISchedulingRule, org.eclipse.jface.operation.IRunnableWithProgress) + * @see org.eclipse.team.internal.ccvs.ui.operations.ITeamRunnableContext#run(java.lang.String, org.eclipse.core.runtime.jobs.ISchedulingRule, org.eclipse.jface.operation.IRunnableWithProgress) */ public void run( String title, @@ -43,14 +43,14 @@ public class HeadlessCVSRunnableContext implements ICVSRunnableContext { throws InvocationTargetException, InterruptedException { if (listener != null) { - new CVSNonblockingRunnableContext(listener).run("Headless Job", null, true, runnable); + new JobRunnableContext(listener, null).run("Headless Job", null, true, runnable); } else { runnable.run(new NullProgressMonitor()); } } /* (non-Javadoc) - * @see org.eclipse.team.internal.ccvs.ui.operations.ICVSRunnableContext#getShell() + * @see org.eclipse.team.internal.ccvs.ui.operations.ITeamRunnableContext#getShell() */ public Shell getShell() { return null; diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/MenuEnablementTest.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/MenuEnablementTest.java index 945f4fc11..4c0efec9b 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/MenuEnablementTest.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/MenuEnablementTest.java @@ -18,11 +18,7 @@ import java.util.List; import junit.framework.Test; import junit.framework.TestSuite; -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.ResourcesPlugin; +import org.eclipse.core.resources.*; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; @@ -31,23 +27,7 @@ import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.team.core.TeamException; import org.eclipse.team.internal.ccvs.core.CVSException; import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer; -import org.eclipse.team.internal.ccvs.ui.actions.AddAction; -import org.eclipse.team.internal.ccvs.ui.actions.BranchAction; -import org.eclipse.team.internal.ccvs.ui.actions.CommitAction; -import org.eclipse.team.internal.ccvs.ui.actions.CompareWithRemoteAction; -import org.eclipse.team.internal.ccvs.ui.actions.CompareWithRevisionAction; -import org.eclipse.team.internal.ccvs.ui.actions.CompareWithTagAction; -import org.eclipse.team.internal.ccvs.ui.actions.GenerateDiffFileAction; -import org.eclipse.team.internal.ccvs.ui.actions.IgnoreAction; -import org.eclipse.team.internal.ccvs.ui.actions.MergeAction; -import org.eclipse.team.internal.ccvs.ui.actions.ReplaceWithRemoteAction; -import org.eclipse.team.internal.ccvs.ui.actions.ReplaceWithTagAction; -import org.eclipse.team.internal.ccvs.ui.actions.SetKeywordSubstitutionAction; -import org.eclipse.team.internal.ccvs.ui.actions.ShowResourceInHistoryAction; -import org.eclipse.team.internal.ccvs.ui.actions.SyncAction; -import org.eclipse.team.internal.ccvs.ui.actions.TagLocalAction; -import org.eclipse.team.internal.ccvs.ui.actions.UnmanageAction; -import org.eclipse.team.internal.ccvs.ui.actions.UpdateAction; +import org.eclipse.team.internal.ccvs.ui.actions.*; import org.eclipse.team.tests.ccvs.core.CVSTestSetup; import org.eclipse.team.tests.ccvs.core.EclipseTest; import org.eclipse.ui.IActionDelegate; @@ -323,22 +303,6 @@ public class MenuEnablementTest extends EclipseTest { assertEnablement(action, project, UNMANAGED_PARENT, true /* expected enablement */); } - public void testCompareWithRemoteAction() throws CoreException, TeamException { - IActionDelegate action = new CompareWithRemoteAction(); - IProject project = createTestProject(action); - assertDisabledForCommonReasons(action, project); - assertEnabledForFolderOnlyOverlap(action, project); - assertEnablement(action, project, MANAGED, true /* expected enablement */); - assertEnablement(action, project, MANAGED | ADDED, true /* expected enablement */); - assertEnablement(action, project, MANAGED | ADDED | UNMANAGED, true /* expected enablement */); - // true is expected for ignored resources whose parent is not ignored - assertEnablement(action, project, IGNORED, true /* expected enablement */); - assertEnablement(action, project, UNMANAGED, true /* expected enablement */); - assertEnablement(action, project, UNMANAGED_PARENT, false /* expected enablement */); - // true is expected for ignored resources whose parent is not ignored - assertEnablement(action, project, UNMANAGED | MANAGED | IGNORED, true /* expected enablement */); - } - public void testCompareWithRevison() throws CoreException, TeamException { IActionDelegate action = new CompareWithRevisionAction(); IProject project = createTestProject(action); diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/SynchronizeViewTestAdapter.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/SynchronizeViewTestAdapter.java index d1c9006af..cb59c581f 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/SynchronizeViewTestAdapter.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/SynchronizeViewTestAdapter.java @@ -16,17 +16,17 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.swt.widgets.Display; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.SyncInfo; -import org.eclipse.team.core.subscribers.TeamSubscriber; -import org.eclipse.team.internal.ccvs.core.CVSMergeSubscriber; -import org.eclipse.team.internal.ccvs.core.CVSTag; +import org.eclipse.team.core.subscribers.Subscriber; +import org.eclipse.team.core.subscribers.SubscriberSyncInfoCollector; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.internal.ccvs.core.*; +import org.eclipse.team.internal.ccvs.ui.subscriber.CompareParticipant; import org.eclipse.team.internal.ccvs.ui.subscriber.MergeSynchronizeParticipant; -import org.eclipse.team.internal.ui.synchronize.sets.SubscriberInput; -import org.eclipse.team.internal.ui.synchronize.sets.SyncSet; import org.eclipse.team.tests.ccvs.core.EclipseTest; import org.eclipse.team.tests.ccvs.core.subscriber.SyncInfoSource; import org.eclipse.team.ui.TeamUI; import org.eclipse.team.ui.synchronize.*; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; /** * SyncInfoSource that obtains SyncInfo from the SynchronizeView's SyncSet. @@ -37,12 +37,11 @@ public class SynchronizeViewTestAdapter extends SyncInfoSource { TeamUI.getSynchronizeManager().showSynchronizeViewInActivePage(null); } - public SyncInfo getSyncInfo(TeamSubscriber subscriber, IResource resource) throws TeamException { - SubscriberInput input = getInput(subscriber); - SyncSet set = input.getWorkingSetSyncSet(); + public SyncInfo getSyncInfo(Subscriber subscriber, IResource resource) throws TeamException { + SyncInfoSet set = getCollector(subscriber).getSubscriberSyncInfoSet(); SyncInfo info = set.getSyncInfo(resource); if (info == null) { - info = subscriber.getSyncInfo(resource, DEFAULT_MONITOR); + info = subscriber.getSyncInfo(resource); if ((info != null && info.getKind() != SyncInfo.IN_SYNC)) { throw new AssertionFailedError(); } @@ -50,31 +49,35 @@ public class SynchronizeViewTestAdapter extends SyncInfoSource { return info; } - private SubscriberInput getInput(TeamSubscriber subscriber) { + private SubscriberParticipant getParticipant(Subscriber subscriber) { // show the sync view ISynchronizeParticipant[] participants = TeamUI.getSynchronizeManager().getSynchronizeParticipants(); for (int i = 0; i < participants.length; i++) { ISynchronizeParticipant participant = participants[i]; - if(participant instanceof TeamSubscriberParticipant) { - SubscriberInput input = ((TeamSubscriberParticipant)participant).getInput(); - TeamSubscriber s = input.getSubscriber(); - if(s == subscriber) { - EclipseTest.waitForSubscriberInputHandling(input); - return input; + if(participant instanceof SubscriberParticipant) { + if(((SubscriberParticipant)participant).getSubscriber() == subscriber) { + return (SubscriberParticipant)participant; } } } return null; } + + private SubscriberSyncInfoCollector getCollector(Subscriber subscriber) { + SubscriberParticipant participant = getParticipant(subscriber); + if (participant == null) return null; + SubscriberSyncInfoCollector syncInfoCollector = participant.getSubscriberSyncInfoCollector(); + EclipseTest.waitForSubscriberInputHandling(syncInfoCollector); + return syncInfoCollector; + } /* (non-Javadoc) * @see org.eclipse.team.tests.ccvs.core.subscriber.SyncInfoSource#assertProjectRemoved(org.eclipse.team.core.subscribers.TeamSubscriber, org.eclipse.core.resources.IProject) */ - protected void assertProjectRemoved(TeamSubscriber subscriber, IProject project) throws TeamException { + protected void assertProjectRemoved(Subscriber subscriber, IProject project) throws TeamException { super.assertProjectRemoved(subscriber, project); - SubscriberInput input = getInput(subscriber); - SyncSet set = input.getFilteredSyncSet(); - if (set.getOutOfSyncDescendants(project).length != 0) { + SyncInfoTree set = getCollector(subscriber).getSyncInfoTree(); + if (set.hasMembers(project)) { throw new AssertionFailedError("The sync set still contains resources from the deleted project " + project.getName()); } } @@ -95,6 +98,20 @@ public class SynchronizeViewTestAdapter extends SyncInfoSource { /* (non-Javadoc) + * @see org.eclipse.team.tests.ccvs.core.subscriber.SyncInfoSource#createCompareSubscriber(org.eclipse.core.resources.IProject, org.eclipse.team.internal.ccvs.core.CVSTag) + */ + public CVSCompareSubscriber createCompareSubscriber(IProject project, CVSTag tag) { + CVSCompareSubscriber s = super.createCompareSubscriber(project, tag); + ISynchronizeManager synchronizeManager = TeamUI.getSynchronizeManager(); + ISynchronizeParticipant participant = new CompareParticipant(s); + synchronizeManager.addSynchronizeParticipants( + new ISynchronizeParticipant[] {participant}); + ISynchronizeView view = synchronizeManager.showSynchronizeViewInActivePage(null); + view.display(participant); + return s; + } + + /* (non-Javadoc) * @see org.eclipse.team.tests.ccvs.core.subscriber.SyncInfoSource#tearDown() */ public void tearDown() { @@ -112,16 +129,17 @@ public class SynchronizeViewTestAdapter extends SyncInfoSource { /* (non-Javadoc) * @see org.eclipse.team.tests.ccvs.core.subscriber.SyncInfoSource#refresh(org.eclipse.team.core.subscribers.TeamSubscriber, org.eclipse.core.resources.IResource) */ - public void refresh(TeamSubscriber subscriber, IResource resource) throws TeamException { + public void refresh(Subscriber subscriber, IResource resource) throws TeamException { super.refresh(subscriber, resource); - EclipseTest.waitForSubscriberInputHandling(getInput(subscriber)); + // Getting the collector waits for the subscriber input handlers + getCollector(subscriber); } /* (non-Javadoc) * @see org.eclipse.team.tests.ccvs.core.subscriber.SyncInfoSource#reset() */ - public void reset(TeamSubscriber subscriber) throws TeamException { + public void reset(Subscriber subscriber) throws TeamException { super.reset(subscriber); - getInput(subscriber).reset(); + getCollector(subscriber).reset(); } } diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/ArgumentParser.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/ArgumentParser.java deleted file mode 100644 index f206dbed4..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/ArgumentParser.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.tests.ccvs.ui.old; - - -public class ArgumentParser { - protected ArgumentParser() { - } - - public boolean parse(String[] args) { - int index = 0; - String option = null; - for (int i = 0; i < args.length; i++) { - String arg = args[i]; - if (arg == null) continue; - if (arg.charAt(0) == '-') { - if (option != null && ! handleOption(option, null)) return false; - option = arg; - } else if (option != null) { - if (! handleOption(option, arg)) return false; - option = null; - } else { - if (! handleArgument(index++, arg)) return false; - } - } - if (option != null && ! handleOption(option, null)) return false; - return handleFinished(); - } - - protected boolean handleFinished() { - return true; - } - - protected boolean handleArgument(int index, String arg) { - return false; - } - - protected boolean handleOption(String option, String arg) { - return false; - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/BenchmarkTestSetup.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/BenchmarkTestSetup.java deleted file mode 100644 index 0b9ef08ba..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/BenchmarkTestSetup.java +++ /dev/null @@ -1,55 +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.tests.ccvs.ui.old; - - -import java.io.File; -import java.io.IOException; -import java.net.URL; - -import junit.framework.Test; -import org.eclipse.core.runtime.IPluginDescriptor; -import org.eclipse.core.runtime.IPluginRegistry; -import org.eclipse.core.runtime.Platform; -import org.eclipse.team.tests.ccvs.core.CVSTestSetup; - -public class BenchmarkTestSetup extends CVSTestSetup { - public static final File BIG_ZIP_FILE; - public static final File SMALL_ZIP_FILE; - public static final File TINY_ZIP_FILE; - - // Static initializer for constants - static { - try { - BIG_ZIP_FILE = getTestFile("benchmarkBig.zip"); - SMALL_ZIP_FILE = getTestFile("benchmarkSmall.zip"); - TINY_ZIP_FILE = getTestFile("benchmarkTiny.zip"); - } catch (IOException e) { - throw new Error(e.getMessage()); - } - } - - public static File getTestFile(String name) throws IOException { - IPluginRegistry registry = Platform.getPluginRegistry(); - IPluginDescriptor descriptor = registry.getPluginDescriptor("org.eclipse.team.tests.cvs.core"); - URL baseURL = descriptor.getInstallURL(); - URL url = new URL(baseURL, "resources/BenchmarkTest/" + name); - url = Platform.asLocalURL(url); - if (url.getProtocol().equals("file")) { - return new File(url.getFile()).getAbsoluteFile(); - } - throw new IOException("Cannot find test file: " + name); - } - - public BenchmarkTestSetup(Test test) { - super(test); - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/CVSUITestCase.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/CVSUITestCase.java deleted file mode 100644 index 5ed517ddc..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/CVSUITestCase.java +++ /dev/null @@ -1,465 +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.tests.ccvs.ui.old; - - -import java.io.File; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import junit.framework.Test; - -import org.eclipse.compare.structuremergeviewer.DiffNode; -import org.eclipse.compare.structuremergeviewer.IDiffContainer; -import org.eclipse.compare.structuremergeviewer.IDiffElement; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.IWorkspaceDescription; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.swt.widgets.Display; -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.CVSTag; -import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder; -import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation; -import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; -import org.eclipse.team.internal.ccvs.ui.ICVSUIConstants; -import org.eclipse.team.internal.ccvs.ui.actions.AddToWorkspaceAction; -import org.eclipse.team.internal.ccvs.ui.actions.CommitAction; -import org.eclipse.team.internal.ccvs.ui.actions.ReplaceWithRemoteAction; -import org.eclipse.team.internal.ccvs.ui.actions.UpdateAction; -import org.eclipse.team.internal.ccvs.ui.operations.ITagOperation; -import org.eclipse.team.internal.ccvs.ui.operations.TagOperation; -import org.eclipse.team.internal.ccvs.ui.repo.RepositoryManager; -import org.eclipse.team.internal.ccvs.ui.sync.CVSSyncCompareInput; -import org.eclipse.team.internal.ccvs.ui.sync.CommitSyncAction; -import org.eclipse.team.internal.ccvs.ui.sync.ForceCommitSyncAction; -import org.eclipse.team.internal.ccvs.ui.sync.ForceUpdateSyncAction; -import org.eclipse.team.internal.ccvs.ui.sync.UpdateSyncAction; -import org.eclipse.team.internal.ccvs.ui.wizards.SharingWizard; -import org.eclipse.team.internal.ui.dialogs.IPromptCondition; -import org.eclipse.team.internal.ui.sync.ITeamNode; -import org.eclipse.team.internal.ui.sync.SyncSet; -import org.eclipse.team.internal.ui.sync.SyncView; -import org.eclipse.team.tests.ccvs.core.CVSTestSetup; -import org.eclipse.ui.IActionDelegate; -import org.eclipse.ui.IObjectActionDelegate; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.WorkbenchException; - -public class CVSUITestCase extends LoggingTestCase { - protected static Set installedTrap = new HashSet(); - private List testWindows; - protected IWorkbenchWindow testWindow; - protected CVSRepositoryLocation testRepository; - protected boolean USE_CONSOLE = System.getProperty("cvs.tests.use_console") != null; - protected boolean SHOW_CONSOLE = System.getProperty("cvs.tests.show_console") != null; - - public CVSUITestCase(Test test) { - super(test); - testWindows = new ArrayList(3); - } - - public void setUp() throws CoreException{ - super.setUp(); - testRepository = CVSTestSetup.repository; - testWindow = openTestWindow(); - - Display display = testWindow.getShell().getDisplay(); - if (! installedTrap.contains(display)) { - installedTrap.add(display); - Utils.waitForErrorDialog(display, 10000 /*ms*/, new Waiter() { - public boolean notify(Object object) { - Dialog dialog = (Dialog) object; - printWarning("Encountered error dialog with title: " + dialog.getShell().getText(), null, null); - dialog.close(); - return true; - } - }); - } - - // disable auto-build - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - IWorkspaceDescription description = workspace.getDescription(); - description.setAutoBuilding(false); - try { - workspace.setDescription(description); - } catch (CoreException e) { - throw new CVSException(e); - } - - // disable CVS GZIP compression - IPreferenceStore store = CVSUIPlugin.getPlugin().getPreferenceStore(); - store.setValue(ICVSUIConstants.PREF_COMPRESSION_LEVEL, 0); - CVSProviderPlugin.getPlugin().setCompressionLevel(0); - - // default case is to not show the console but don't disable it, this is - // the typical user experience. - if(SHOW_CONSOLE) { - //showConsole(); - } else if(!USE_CONSOLE) { - CVSProviderPlugin.getPlugin().setConsoleListener(null); - } - - // wait for UI to settle - Utils.processEventsUntil(100); - } - - public void tearDown() throws CVSException { - // wait for UI to settle - Utils.processEventsUntil(100); - closeAllTestWindows(); - super.tearDown(); - } - - /** - * Open a test window with the empty perspective. - */ - protected IWorkbenchWindow openTestWindow() { - try { - IWorkbenchWindow win = PlatformUI.getWorkbench().openWorkbenchWindow( - EmptyPerspective.PERSP_ID, ResourcesPlugin.getWorkspace()); - testWindows.add(win); - return win; - } catch (WorkbenchException e) { - fail(); - return null; - } - } - - /** - * Close all test windows. - */ - protected void closeAllTestWindows() { - Iterator iter = testWindows.iterator(); - IWorkbenchWindow win; - while (iter.hasNext()) { - win = (IWorkbenchWindow) iter.next(); - win.close(); - } - testWindows.clear(); - } - - /** - * Checks out the projects with the specified tags from the test repository. - */ - protected void actionCheckoutProjects(String[] projectNames, CVSTag[] tags) throws Exception { - ICVSRemoteFolder[] projects = lookupRemoteProjects(projectNames, tags); - AddToWorkspaceAction action = new AddToWorkspaceAction() { - protected IPromptCondition getOverwriteLocalAndFileSystemPrompt() { - return new DummyPromptCondition(); - } - }; - runActionDelegate(action, projects, "Repository View Checkout action"); - timestampGranularityHiatus(); - } - - /** - * Replaces the specified resources with the remote contents using the action contribution. - */ - protected void actionReplaceWithRemote(IResource[] resources) { - ReplaceWithRemoteAction action = new ReplaceWithRemoteAction() { - protected IPromptCondition getPromptCondition(IResource[] resources) { - return new DummyPromptCondition(); - } - }; - runActionDelegate(action, resources, "Replace with Remote action"); - timestampGranularityHiatus(); - } - - /** - * Shares the specified project with the test repository. - * @param project the project to share - */ - protected void actionShareProject(IProject project) { - final SharingWizard wizard = new SharingWizard(); - wizard.init(PlatformUI.getWorkbench(), project); - Utils.waitForWizardToOpen(testWindow.getShell(), wizard, new Waiter() { - public boolean notify(Object object) { - WizardDialog dialog = (WizardDialog) object; - startTask("set sharing, pop up sync viewer"); - wizard.performFinish(); - endTask(); - dialog.close(); - return false; - } - }); - timestampGranularityHiatus(); - } - - /** - * Updates the specified resources using the action contribution. - */ - protected void actionCVSCommit(IResource[] resources, final String comment) { - assertNotNull(comment); - CommitAction action = new CommitAction() { - protected String promptForComment() { - return comment; - } - }; - runActionDelegate(action, resources, "CVS Commit action"); - timestampGranularityHiatus(); - } - - /** - * Tags the specified resources using the action contribution. - */ - protected void actionCVSTag(IResource[] resources, final String name) { - assertNotNull(name); - ITagOperation op = new TagOperation(null, resources); - op.setTag(new CVSTag(name, CVSTag.VERSION)); - try { - op.run(); - } catch (InterruptedException e) { - printWarning("Tag interrupted", e, null); - } catch (CVSException e) { - printWarning("Tag failed", e, null); - } - } - - /** - * Updates the specified resources using the action contribution. - */ - protected void actionCVSUpdate(IResource[] resources) { - runActionDelegate(new UpdateAction(), resources, "CVS Update action"); - timestampGranularityHiatus(); - } - - /** - * Pops up the synchronizer view for the specified resources. - * @param resources the resources to sync - * @return the compare input used - */ - protected CVSSyncCompareInput syncResources(IResource[] resources) { - startTask("Synchronize with Repository action"); - SyncView syncView = getSyncView(); - CVSSyncCompareInput input = new CVSSyncCompareInput(resources) { - // overridden to prevent "nothing to synchronize" dialog from popping up - public void run(IProgressMonitor monitor) - throws InvocationTargetException, InterruptedException { - super.run(monitor); - DiffNode result = getDiffRoot(); // (DiffNode) getCompareResult() - if (result == null || Utils.isEmpty(result)) throw new InterruptedException(); - } - }; - syncView.showSync(input); - endTask(); - return input; - } - - /** - * Commits the specified resources using the synchronizer view. - * @param resources the resources to commit - * @param input the compare input for the sync view, or null to create a new one - * @param comment the comment string, or "" - */ - protected void syncCommitResources(IResource[] resources, CVSSyncCompareInput input, String comment) { - if (input == null) input = syncResources(resources); - IDiffContainer diffRoot = input.getDiffRoot(); - if (Utils.isEmpty(diffRoot)) { - startTask("Nothing to Commit"); - } else { - ITeamNode[] nodes = getTeamNodesForResources(diffRoot, resources); - startTask("Sync View Commit action"); - syncCommitInternal(input, nodes, comment); - } - endTask(); - timestampGranularityHiatus(); - } - - /** - * Updates the specified resources using the synchronizer view. - * @param resources the resources to update - * @param input the compare input for the sync view, or null to create a new one - * @param comment the comment string, or "" - */ - protected void syncUpdateResources(IResource[] resources, CVSSyncCompareInput input) { - if (input == null) input = syncResources(resources); - IDiffContainer diffRoot = input.getDiffRoot(); - if (Utils.isEmpty(diffRoot)) { - startTask("Nothing to Update"); - } else { - ITeamNode[] nodes = getTeamNodesForResources(diffRoot, resources); - startTask("Sync View Update action"); - syncGetInternal(input, nodes); - } - endTask(); - timestampGranularityHiatus(); - } - - /** - * Creates and imports project contents from a zip file. - */ - protected IProject createAndImportProject(String prefix, File zipFile) throws Exception { - IProject project = Utils.createUniqueProject(prefix); - Utils.importZip(project, zipFile); - return project; - } - - /** - * Looks up handles for remote projects by name. - */ - protected ICVSRemoteFolder[] lookupRemoteProjects(String[] projectNames, CVSTag[] tags) throws Exception { - ICVSRemoteFolder[] folders = new ICVSRemoteFolder[projectNames.length]; - for (int i = 0; i < projectNames.length; ++i) { - folders[i] = testRepository.getRemoteFolder(projectNames[i], tags[i]); - } - return folders; - } - - /** - * Gets an instance of the Synchronize view - */ - protected SyncView getSyncView() { - SyncView view = SyncView.findViewInActivePage(null); - assertNotNull("Could not obtain a Sync View.", view); - return view; - } - - /** - * Runs an IActionDelegate prototype instance on a given selection. - */ - protected void runActionDelegate(IActionDelegate delegate, Object[] selection, String taskName) { - Action action = new Action() { }; - if (delegate instanceof IObjectActionDelegate) { - ((IObjectActionDelegate) delegate).setActivePart(action, - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPartService().getActivePart()); - } - delegate.selectionChanged(action, new StructuredSelection(selection)); - startTask(taskName); - delegate.run(action); - endTask(); - } - - /** - * Commits NON-CONFLICTING and CONFLICTING resources represented by an array of synchronizer nodes. - */ - private void syncCommitInternal(CVSSyncCompareInput input, ITeamNode[] nodes, final String comment) { - FakeSelectionProvider selectionProvider = new FakeSelectionProvider(nodes); - // Commit ONLY NON-CONFLICTING changes - CommitSyncAction commitAction = new CommitSyncAction(input, selectionProvider, "Commit", - testWindow.getShell()) { - protected int promptForConflicts(SyncSet syncSet) { - return 0; // yes! sync conflicting changes - } - protected String promptForComment(RepositoryManager manager, IResource[] resourcesToCommit) { - return comment; - } - protected IResource[] promptForResourcesToBeAdded(RepositoryManager manager, IResource[] unadded) { - return unadded; - } - }; - commitAction.run(); - // Commit ONLY CONFLICTING changes - ForceCommitSyncAction forceCommitAction = new ForceCommitSyncAction(input, selectionProvider, "Force Commit", - testWindow.getShell()) { - protected int promptForConflicts(SyncSet syncSet) { - return 0; // yes! sync conflicting changes - } - protected String promptForComment(RepositoryManager manager, IResource[] resourcesToCommit) { - return comment; - } - protected IResource[] promptForResourcesToBeAdded(RepositoryManager manager, IResource[] unadded) { - return unadded; - } - }; - forceCommitAction.run(); - } - - /** - * Updates NON-CONFLICTING and CONFLICTING resources represented by an array of synchronizer nodes. - */ - private void syncGetInternal(CVSSyncCompareInput input, ITeamNode[] nodes) { - FakeSelectionProvider selectionProvider = new FakeSelectionProvider(nodes); - // Update ONLY NON-CONFLICTING changes - UpdateSyncAction updateAction = new UpdateSyncAction(input, selectionProvider, "Update", - testWindow.getShell()) { - protected boolean promptForConflicts() { - return true; - } - protected int promptForMergeableConflicts() { - return 2; - } - }; - updateAction.run(); - // Update ONLY CONFLICTING changes - ForceUpdateSyncAction forceUpdateAction = new ForceUpdateSyncAction(input, selectionProvider, "Force Update", - testWindow.getShell()) { - protected boolean promptForConflicts() { - return true; - } - protected int promptForMergeableConflicts() { - return 2; - } - }; - forceUpdateAction.run(); - } - - /** - * Gets an array of synchronizer nodes corresponding to an array of resouces. - */ - protected static ITeamNode[] getTeamNodesForResources(IDiffContainer root, IResource[] resources) { - ITeamNode[] nodes = new ITeamNode[resources.length]; - for (int i = 0; i < resources.length; ++i) { - nodes[i] = findTeamNodeForResource(root, resources[i]); - assertNotNull(nodes[i]); - } - return nodes; - } - - private static ITeamNode findTeamNodeForResource(IDiffElement root, IResource resource) { - RepositoryProvider provider = RepositoryProvider.getProvider(resource.getProject(), CVSProviderPlugin.getTypeId()); - assertNotNull("Resource " + resource.getFullPath() + " must have an associated CVSProvider", provider); - - if (root instanceof ITeamNode) { - ITeamNode node = (ITeamNode) root; - if (resource.equals(node.getResource())) return node; - // prune the backtracking tree - IResource parent = resource.getParent(); - do { - if (parent == null) return null; // can't possibly be child of this node - } while (! resource.equals(parent)); - } - if (root instanceof IDiffContainer) { - IDiffContainer container = (IDiffContainer) root; - if (container.hasChildren()) { - IDiffElement[] children = container.getChildren(); - for (int i = 0; i < children.length; ++i) { - ITeamNode node = findTeamNodeForResource(children[i], resource); - if (node != null) return node; - } - } - } - return null; - } - - /** - * Waits for a small amount of time to compensate for file system time stamp granularity. - */ - private void timestampGranularityHiatus() { - //JUnitTestCase.waitMsec(1500); - Utils.processEventsUntil(1500); - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/CaseEntry.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/CaseEntry.java deleted file mode 100644 index 8b59e3153..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/CaseEntry.java +++ /dev/null @@ -1,38 +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.tests.ccvs.ui.old; - - -import org.xml.sax.Attributes; - -public class CaseEntry extends LogEntryContainer { - private String className; - - public CaseEntry(LogEntryContainer parent, Attributes attributes) { - this(parent, attributes.getValue("name"), attributes.getValue("class")); - } - - public CaseEntry(LogEntryContainer parent, String name, String className) { - super(parent, name); - this.className = (className != null) ? className : "unknown"; - } - - public void accept(ILogEntryVisitor visitor) { - visitor.visitCaseEntry(this); - } - - /** - * Returns the class name of the test case. - */ - public String getClassName() { - return className; - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/CommandTests.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/CommandTests.java deleted file mode 100644 index b850dd000..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/CommandTests.java +++ /dev/null @@ -1,237 +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.tests.ccvs.ui.old; - - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import junit.framework.Test; -import junit.framework.TestSuite; - -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.IResourceVisitor; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.Path; -import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.CVSTag; -import org.eclipse.team.internal.ccvs.core.client.Command.KSubstOption; -import org.eclipse.team.tests.ccvs.core.CommandLineCVSClient; -import org.eclipse.team.tests.ccvs.core.EclipseCVSClient; -import org.eclipse.team.tests.ccvs.core.ICVSClient; - -public class CommandTests extends CVSUITestCase { - private String baseName; - private IProject referenceProject; - private IProject eclipseProject; - private IProject uiProject; - - public CommandTests(Test test) { - super(test); - } - public static Test suite() { - return new BenchmarkTestSetup(new TestSuite(CommandTests.class)); - } - - public void setUp() throws CoreException { - super.setUp(); - try { - baseName = Utils.makeUniqueName(null, "thisproject", null); - referenceProject = Utils.createProject(baseName + "-reference"); - eclipseProject = Utils.createProject(baseName + "-eclipse"); - uiProject = Utils.createProject(baseName); - } catch (CoreException e) { - throw new CVSException(e); - } - } - - public void testImportAddCommitCheckout() throws Throwable { - // import a project using each client - new ComparativeTest("import/add/commit big project") { - protected void runCommandTest(final IContainer localRoot, ICVSClient client) throws Exception { - // use the import command to create a new module - IFolder folder = localRoot.getFolder(new Path("empty_folder")); - folder.create(false /*force*/, true /*local*/, null); - execute(client, "import empty module", folder, "import", - new String[] { }, - new String[] { "-m", "initial import" }, - new String[] { localRoot.getName(), "vendor", "start" }); - folder.delete(false /*force*/, null); - - // checkout the project - localRoot.delete(false /*force*/, null); - execute(client, "checkout module", localRoot.getParent(), "co", - new String[] { }, - new String[] { }, - new String[] { localRoot.getName() }); - - // prepare contents - prepareContents(localRoot); - - // determine the set of files and folders to be added - final Map /* from KSubstOption to String */ files = new HashMap(); - final Set /* of String */ folders = new TreeSet(); - final int trim = localRoot.getProjectRelativePath().segmentCount(); - localRoot.accept(new IResourceVisitor() { - public boolean visit(IResource resource) throws CoreException { - if (! resource.equals(localRoot)) { - String name = resource.getProjectRelativePath().removeFirstSegments(trim).toString(); - if (resource.getType() == IResource.FILE) { - KSubstOption ksubst = KSubstOption.fromFile((IFile) resource); - Set set = (Set) files.get(ksubst); - if (set == null) { - set = new HashSet(); - files.put(ksubst, set); - } - set.add(name); - } else { - folders.add(name); - } - } - return true; - } - }, IResource.DEPTH_INFINITE, false); - - // add all folders - if (!folders.isEmpty()) { - executeInParts(client, "add folders", localRoot, "add", - new String[] { }, - new String[] { }, - (String[])folders.toArray(new String[folders.size()])); - } - // add all files - for (Iterator it = files.entrySet().iterator(); it.hasNext();) { - Map.Entry entry = (Map.Entry) it.next(); - KSubstOption ksubst = (KSubstOption) entry.getKey(); - Set set = (Set) entry.getValue(); - executeInParts(client, "add files (" + ksubst.getShortDisplayText() + ")", localRoot, "add", - new String[] { }, - new String[] { ksubst.toString() }, - (String[])set.toArray(new String[set.size()])); - } - - // commit everything - execute(client, "commit module", localRoot, "ci", - new String[] { }, - new String[] { "-m", "dummy message" }, - new String[] { }); - } - protected void runUITest(IContainer localRoot) throws Exception { - prepareContents(localRoot); - actionShareProject(uiProject); - syncCommitResources(new IResource[] { uiProject }, null, "initial"); - } - private void prepareContents(IContainer localRoot) throws Exception { - Utils.importZip(localRoot, BenchmarkTestSetup.BIG_ZIP_FILE); - } - }.run(); - - // check it out using each client - new ComparativeTest("checkout big project") { - protected void runCommandTest(IContainer localRoot, ICVSClient client) throws Exception { - execute(client, "checkout module", localRoot.getParent(), "co", - new String[] { }, - new String[] { "-P" }, - new String[] { localRoot.getName() }); - } - protected void runUITest(IContainer localRoot) throws Exception { - actionCheckoutProjects(new String[] { localRoot.getName() }, new CVSTag[] { CVSTag.DEFAULT }); - } - protected void setUp(IContainer localRoot) throws Exception { - // delete then recreate the container - IProject project = (IProject) localRoot; - Utils.deleteProject(project); - project.create(null); - project.open(null); - // delete the .project file (avoid .project is in the way error) - IFile file = project.getFile(".project"); - file.delete(false /*force*/, null); - } - }.run(); - } - - protected abstract class ComparativeTest { - private String name; - public ComparativeTest(String name) { - this.name = name; - } - public void run() throws Exception { - startGroup(name); - - startGroup("command line client"); - setUp(referenceProject); - runCommandTest(referenceProject, CommandLineCVSClient.INSTANCE); - tearDown(referenceProject); - endGroup(); - - startGroup("eclipse client"); - setUp(eclipseProject); - runCommandTest(eclipseProject, EclipseCVSClient.INSTANCE); - tearDown(eclipseProject); - endGroup(); - - startGroup("user interface"); - setUp(uiProject); - runUITest(uiProject); - tearDown(uiProject); - endGroup(); - - endGroup(); - } - protected abstract void runCommandTest(IContainer localRoot, ICVSClient client) throws Exception ; - protected abstract void runUITest(IContainer localRoot) throws Exception; - protected void setUp(IContainer localRoot) throws Exception { - } - protected void tearDown(IContainer localRoot) throws Exception { - } - protected void execute(ICVSClient client, String taskname, - IContainer localRoot, String command, - String[] globalOptions, String[] localOptions, String[] arguments) throws CVSException { - // The execution time for the client will include overhead associated with - // computing the command to be run and cleaning up Eclipse state once it has - // completed, including notifying resource delta listener. Since all clients - // in the Eclipse environment are subject to this overhead, the theory is that - // it will be a constant factor that we can neglect. - startTask(taskname); - client.executeCommand(testRepository, localRoot, command, globalOptions, localOptions, arguments); - endTask(); - } - protected void executeInParts(ICVSClient client, String taskname, - IContainer localRoot, String command, - String[] globalOptions, String[] localOptions, String[] arguments) throws CVSException { - // There are problems executing commands with too many arguments - // so we have to break them up into chunks. - startTask(taskname); - int i = 0; - do { - int len = Math.min(200, arguments.length - i); - String[] args; - if (i == 0 && len == arguments.length) { - args = arguments; - } else { - args = new String[len]; - System.arraycopy(arguments, i, args, 0, len); - } - client.executeCommand(testRepository, localRoot, command, globalOptions, localOptions, args); - i += len; - } while (arguments.length - i > 0); - endTask(); - } - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/DelimitedValuesWriter.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/DelimitedValuesWriter.java deleted file mode 100644 index 2146320e7..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/DelimitedValuesWriter.java +++ /dev/null @@ -1,54 +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.tests.ccvs.ui.old; - - -import java.io.PrintStream; - -public class DelimitedValuesWriter { - private static final String BEGIN_QUOTE = "\""; - private static final String END_QUOTE = "\""; - private PrintStream ps; - private String delimiter; - private boolean quoted; - private boolean firstField; - - public DelimitedValuesWriter(PrintStream ps, String delimiter, boolean quoted) { - this.ps = ps; - this.delimiter = delimiter; - this.quoted = quoted; - this.firstField = true; - } - - public void printField(String field) { - if (firstField) { - firstField = false; - } else { - ps.print(delimiter); - } - if (quoted) ps.print(BEGIN_QUOTE); - ps.print(field); - if (quoted) ps.print(END_QUOTE); - } - public void printFields(String[] fields) { - for (int i = 0; i < fields.length; i++) { - printField(fields[i]); - } - } - public void printRecord(String[] fields) { - printFields(fields); - endRecord(); - } - public void endRecord() { - ps.println(); - firstField = true; - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/EmptyPerspective.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/EmptyPerspective.java deleted file mode 100644 index 91435094b..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/EmptyPerspective.java +++ /dev/null @@ -1,54 +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.tests.ccvs.ui.old; - - -import org.eclipse.ui.IPageLayout; -import org.eclipse.ui.IPerspectiveFactory; - -/** - * This perspective is used for testing api. It defines an initial - * layout with no parts, just an editor area. - * - * Note: originally borrowed from org.eclipse.jdt.junit.eclipse.util - */ -public class EmptyPerspective implements IPerspectiveFactory { - - /** - * The perspective id. - */ - public static final String PERSP_ID = "org.eclipse.team.tests.ccvs.ui.EmptyPerspective"; - - /** - * Constructs a new Default layout engine. - */ - public EmptyPerspective() { - super(); - } - - /** - * Defines the initial layout for a perspective. - * - * Implementors of this method may add additional views to a - * perspective. The perspective already contains an editor folder - * with <code>ID = ILayoutFactory.ID_EDITORS</code>. Add additional views - * to the perspective in reference to the editor folder. - * - * This method is only called when a new perspective is created. If - * an old perspective is restored from a persistence file then - * this method is not called. - * - * @param factory the factory used to add views to the perspective - */ - public void createInitialLayout(IPageLayout layout) { - //layout.addView( MockViewPart.ID, IPageLayout.BOTTOM, 0.5f, layout.getEditorArea() ); - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/FakeSelectionProvider.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/FakeSelectionProvider.java deleted file mode 100644 index dbae25df5..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/FakeSelectionProvider.java +++ /dev/null @@ -1,42 +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.tests.ccvs.ui.old; - - -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.StructuredSelection; - -/** - * Serves up fake selections. - * - * Note: originally borrowed from org.eclipse.jdt.ui.tests.actions - */ -public class FakeSelectionProvider implements ISelectionProvider { - private Object[] fElems; - public FakeSelectionProvider(Object[] elements){ - fElems = elements; - } - - public void addSelectionChangedListener(ISelectionChangedListener listener) { - } - - public ISelection getSelection() { - return new StructuredSelection(fElems); - } - - public void removeSelectionChangedListener(ISelectionChangedListener listener) { - } - - public void setSelection(ISelection selection) { - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/GroupEntry.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/GroupEntry.java deleted file mode 100644 index 094558c6c..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/GroupEntry.java +++ /dev/null @@ -1,28 +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.tests.ccvs.ui.old; - - -import org.xml.sax.Attributes; - -public class GroupEntry extends LogEntryContainer { - public GroupEntry(LogEntryContainer parent, Attributes attributes) { - this(parent, attributes.getValue("name")); - } - - public GroupEntry(LogEntryContainer parent, String name) { - super(parent, name); - } - - public void accept(ILogEntryVisitor visitor) { - visitor.visitGroupEntry(this); - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/ICriteria.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/ICriteria.java deleted file mode 100644 index 3b84b7a67..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/ICriteria.java +++ /dev/null @@ -1,23 +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.tests.ccvs.ui.old; - - -/** - * Generic object filter mechanism. - */ -public interface ICriteria { - /** - * Returns true if the candidate object satisfies the specified - * criteria value according to a particular algorithm. - */ - public boolean test(Object candidate, Object value); -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/ILogEntryVisitor.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/ILogEntryVisitor.java deleted file mode 100644 index e9842b2c5..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/ILogEntryVisitor.java +++ /dev/null @@ -1,19 +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.tests.ccvs.ui.old; - - -public interface ILogEntryVisitor { - public void visitRootEntry(RootEntry entry); - public void visitCaseEntry(CaseEntry entry); - public void visitGroupEntry(GroupEntry entry); - public void visitTaskEntry(TaskEntry entry); -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/LogEntry.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/LogEntry.java deleted file mode 100644 index 8e854ecd1..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/LogEntry.java +++ /dev/null @@ -1,124 +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.tests.ccvs.ui.old; - - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; - -import junit.framework.Assert; -import org.xml.sax.Attributes; -import org.xml.sax.ContentHandler; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.DefaultHandler; -import org.xml.sax.helpers.XMLReaderFactory; - -public abstract class LogEntry { - LogEntryContainer parent; - String name; - - /** - * Creates a new log entry with the specified parent. - * @param parent the parent container - * @param name the name of the entry - */ - public LogEntry(LogEntryContainer parent, String name) { - this.parent = parent; - this.name = name != null ? name : "unknown"; - if (parent != null) parent.addEntry(this); - } - - /** - * Accepts a visitor. - * @param visitor the visitor - */ - public abstract void accept(ILogEntryVisitor visitor); - - /** - * Returns the name of this entry. - */ - public String getName() { - return name; - } - - /** - * Returns the parent container of this entry, or null if none. - */ - public LogEntryContainer getParent() { - return parent; - } - - /** - * Reads an array of log entries from a file. - * @return the log entries - */ - public static RootEntry readLog(File file) throws IOException, SAXException { - XMLReader reader = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser"); - LogContentHandler contentHandler = new LogContentHandler(); - reader.setContentHandler(contentHandler); - reader.parse(new InputSource(new FileInputStream(file))); - return contentHandler.getLogEntries(); - } - - private static class LogContentHandler extends DefaultHandler implements ContentHandler { - private RootEntry root = null; - private LogEntry current = null; - - public RootEntry getLogEntries() { - return root; - } - public void startElement(String uri, String localName, String qName, Attributes attributes) - throws SAXException { - if ("log".equals(localName)) { - Assert.assertNull(current); - current = root = new RootEntry(null, attributes); - } else if ("case".equals(localName)) { - Assert.assertNotNull(current); - Assert.assertTrue(current instanceof RootEntry); - current = new CaseEntry((LogEntryContainer) current, attributes); - } else if ("group".equals(localName)) { - Assert.assertNotNull(current); - Assert.assertTrue(current instanceof CaseEntry || current instanceof GroupEntry); - current = new GroupEntry((LogEntryContainer) current, attributes); - } else if ("task".equals(localName)) { - Assert.assertNotNull(current); - Assert.assertTrue(current instanceof CaseEntry || current instanceof GroupEntry); - current = new TaskEntry((LogEntryContainer) current, attributes); - } else if ("result".equals(localName)) { - Assert.assertNotNull(current); - Assert.assertTrue(current instanceof TaskEntry); - ((TaskEntry) current).addResult(new Result(attributes)); - } else if ("abort".equals(localName)) { - // currently we ignore failure entries - // XXX need a good way to represent failures - } else if ("trace".equals(localName)) { - // currently we ignore stack frames associated with failure entries - } else if ("status".equals(localName)) { - // currently we ignore status associated with failure entries - } else { - throw new SAXException("Unrecognized element: " + localName); - } - } - public void endElement(String uri, String localName, String qName) - throws SAXException { - Assert.assertNotNull(current); - if ("result".equals(localName) || "abort".equals(localName) || - "trace".equals(localName) || "status".equals(localName)) { - // nothing to do - } else { - current = current.getParent(); - } - } - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/LogEntryContainer.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/LogEntryContainer.java deleted file mode 100644 index aca48e393..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/LogEntryContainer.java +++ /dev/null @@ -1,63 +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.tests.ccvs.ui.old; - - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -public abstract class LogEntryContainer extends LogEntry { - private List /* of LogEntry */ list = new ArrayList(); - - public LogEntryContainer(LogEntryContainer parent, String name) { - super(parent, name); - } - - /** - * Accepts a visitor for each child in the order in which they are listed. - * @param visitor the visitor - */ - public void acceptChildren(ILogEntryVisitor visitor) { - Iterator it = list.iterator(); - while (it.hasNext()) { - LogEntry entry = (LogEntry) it.next(); - entry.accept(visitor); - } - } - - /** - * Returns the list of children in this container. - */ - public LogEntry[] members() { - return (LogEntry[]) list.toArray(new LogEntry[list.size()]); - } - - /** - * Returns the member with the specified name and class. - */ - public LogEntry findMember(String name, Class clazz) { - Iterator it = list.iterator(); - while (it.hasNext()) { - LogEntry entry = (LogEntry) it.next(); - if (name.equals(entry.getName()) && - clazz.isAssignableFrom(entry.getClass())) return entry; - } - return null; - } - - /* - * Adds the specified entry to the end of the list. - */ - void addEntry(LogEntry entry) { - list.add(entry); - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/LogFormatterUIMain.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/LogFormatterUIMain.java deleted file mode 100644 index a7ce8a74c..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/LogFormatterUIMain.java +++ /dev/null @@ -1,188 +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.tests.ccvs.ui.old; - - -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.TabFolder; -import org.eclipse.swt.widgets.TabItem; -import org.eclipse.swt.widgets.Text; - -/** - * Quick and dirty UI frontend for the log formatters. - */ -public class LogFormatterUIMain { - - public LogFormatterUIMain() { - } - - public static void main(String[] args) { - new LogFormatterUIMain().run(); - } - - public void run() { - Display display = new Display(); - Shell shell = new Shell(display); - - shell.setText("Log Formatter UI"); - createContents(shell); - - shell.setSize(500, 300); - shell.open(); - while (! shell.isDisposed()) { - if (! display.readAndDispatch()) display.sleep(); - } - shell.dispose(); - display.dispose(); - } - - protected void createContents(Composite parent) { - parent.setLayout(new FillLayout()); - TabFolder tabFolder = new TabFolder(parent, SWT.NONE); - createSummaryTabContents(new TabItem(tabFolder, SWT.NONE)); - createDiffTabContents(new TabItem(tabFolder, SWT.NONE)); - } - - protected void createSummaryTabContents(TabItem item) { - Composite top = new Composite(item.getParent(), SWT.NONE); - item.setControl(top); - item.setText("Create Log Summary"); - GridLayout layout = new GridLayout(); - layout.numColumns = 3; - top.setLayout(layout); - - final Text logFileText = createFileSelector(top, "Log file path: "); - final Text outputFileText = createFileSelector(top, "Output file path: "); - - final Button csvCheckButton = new Button(top, SWT.CHECK); - csvCheckButton.setText("Produce comma separated values data"); - GridData data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_CENTER); - data.horizontalSpan = 3; - csvCheckButton.setLayoutData(data); - - final Button rawCheckButton = new Button(top, SWT.CHECK); - rawCheckButton.setText("Do not merge results from successive iterations"); - data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_CENTER); - data.horizontalSpan = 3; - rawCheckButton.setLayoutData(data); - - createRunButton(top, new Runnable() { - public void run() { - PrintSummaryMain.main(new String[] { - logFileText.getText(), - "-out", outputFileText.getText(), - csvCheckButton.getSelection() ? "-csv" : null, - rawCheckButton.getSelection() ? "-raw" : null }); - } - }); - } - - protected void createDiffTabContents(TabItem item) { - Composite top = new Composite(item.getParent(), SWT.NONE); - item.setControl(top); - item.setText("Create Log Diff"); - GridLayout layout = new GridLayout(); - layout.numColumns = 3; - top.setLayout(layout); - - final Text newerLogFileText = createFileSelector(top, "Newer log file path: "); - final Text olderLogFileText = createFileSelector(top, "Older log file path: "); - final Text outputFileText = createFileSelector(top, "Output file path: "); - - Label label = new Label(top, SWT.NONE); - label.setText("Threshold %"); - label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_CENTER)); - - final Text thresholdText = new Text(top, SWT.BORDER); - thresholdText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER)); - thresholdText.setText("0"); - - new Label(top, SWT.NONE); - - final Button csvCheckButton = new Button(top, SWT.CHECK); - csvCheckButton.setText("Produce comma separated values data"); - GridData data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_CENTER); - data.horizontalSpan = 3; - csvCheckButton.setLayoutData(data); - - final Button ignoreCheckButton = new Button(top, SWT.CHECK); - ignoreCheckButton.setText("Ignore negligible changes in results"); - data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_CENTER); - data.horizontalSpan = 3; - ignoreCheckButton.setLayoutData(data); - - createRunButton(top, new Runnable() { - public void run() { - PrintDiffMain.main(new String[] { - newerLogFileText.getText(), - olderLogFileText.getText(), - "-out", outputFileText.getText(), - "-t", thresholdText.getText(), - csvCheckButton.getSelection() ? "-csv" : null, - ignoreCheckButton.getSelection() ? "-i" : null }); - } - }); - } - - protected Text createFileSelector(Composite parent, String labelText) { - Label label = new Label(parent, SWT.NONE); - label.setText(labelText); - label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_CENTER)); - - final Text text = new Text(parent, SWT.BORDER); - text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER)); - - Button browseButton = new Button(parent, SWT.PUSH); - browseButton.setText("Browse..."); - browseButton.addListener(SWT.Selection, new Listener() { - public void handleEvent(Event event) { - FileDialog dialog = new FileDialog(text.getShell(), SWT.OPEN); - dialog.setFileName(text.getText()); - String name = dialog.open(); - if (name != null) { - text.setText(name); - } - } - }); - browseButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL)); - return text; - } - - protected Button createRunButton(Composite parent, final Runnable runnable) { - Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); - GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_END | GridData.GRAB_VERTICAL); - data.horizontalSpan = 3; - separator.setLayoutData(data); - - final Button runButton = new Button(parent, SWT.PUSH); - runButton.setText("Run"); - data = new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_FILL); - data.horizontalSpan = 3; - runButton.setLayoutData(data); - runButton.addListener(SWT.Selection, new Listener() { - public void handleEvent(Event event) { - runButton.getDisplay().asyncExec(runnable); - } - }); - return runButton; - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/LoggingTestCase.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/LoggingTestCase.java deleted file mode 100644 index b5a389d20..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/LoggingTestCase.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.tests.ccvs.ui.old; - - -import junit.framework.Assert; -import junit.framework.Test; -import junit.framework.TestResult; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.team.tests.ccvs.core.CVSTestSetup; - -public class LoggingTestCase extends CVSTestSetup { - private LoggingTestResult logResult; - private int disableLogStack; - - /** - * Creates a new logging test case. - */ - public LoggingTestCase(Test test) { - super(test); - } - - /** - * Runs a test. - * @param result the result object - */ - public void run(TestResult result) { - // run the garbage collector now to improve benchmark precision - for (int i = 0; i < 4; ++i) { - System.runFinalization(); - System.gc(); - } - if (result instanceof LoggingTestResult) { - logResult = (LoggingTestResult) result; - disableLogStack = 0; - } else { - logResult = null; - disableLogStack = 1; - } - super.run(result); - } - - /** - * Marks the beginning of a new task group. - * @param groupName the name for the group - */ - protected void startGroup(String groupName) { - if (disableLogStack == 0) logResult.startGroup(groupName); - } - - /** - * Marks the ends of the active task group. - */ - protected void endGroup() { - if (disableLogStack == 0) logResult.endGroup(); - } - - /** - * Marks the beginning of a new task. - * @param taskName the name for the task - */ - protected void startTask(String taskName) { - if (disableLogStack == 0) logResult.startTask(taskName); - } - - /** - * Marks the ends of the active task. - */ - protected void endTask() { - if (disableLogStack == 0) logResult.endTask(); - } - - /** - * Disables logging until re-enabled. (this call nests) - */ - protected void disableLog() { - disableLogStack += 1; - } - - /** - * Enables logging when all previous calls to disableLog are matched. - */ - protected void enableLog() { - Assert.assertTrue(disableLogStack > 0); - disableLogStack -= 1; - Assert.assertTrue(disableLogStack != 0 || logResult != null); - } - - /** - * Prints a warning message to the log. - * @param message the message, or null - * @param error an exception with a stack trace, or null - * @param status a status code, or null - */ - protected void printWarning(String message, Throwable error, IStatus status) { - if (disableLogStack == 0) logResult.printWarning(message, error, status); - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/LoggingTestResult.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/LoggingTestResult.java deleted file mode 100644 index dad409d66..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/LoggingTestResult.java +++ /dev/null @@ -1,264 +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.tests.ccvs.ui.old; - - -import java.io.PrintStream; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Stack; -import java.util.StringTokenizer; - -import junit.framework.Assert; -import junit.framework.AssertionFailedError; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestResult; -import junit.runner.BaseTestRunner; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.team.core.TeamException; - -public class LoggingTestResult extends TestResult { - protected Stack groupStack; - protected PerformanceTimer currentTask; - protected PrintStream logStream; - protected Stack /* of String */ elements; - protected String indent; - - /** - * Creates a logging test result. - * @param logStream the output stream, or null to disable logging - */ - public LoggingTestResult(PrintStream logStream) { - this.logStream = logStream; - this.elements = new Stack(); - this.indent = ""; - groupStack = new Stack(); - currentTask = null; - } - - /** - * Marks the beginning of a series of log entries. - */ - public void startLog(long timestamp, String sdkBuild) { - println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); - startXMLElement("log", new String[] { "timestamp", "sdkbuild" }, new String[] { - new SimpleDateFormat("dd/MMM/yyyy HH:mm:ss").format(new Date(timestamp)), - sdkBuild }); - } - - /** - * Marks the end of a series of log entries. - */ - public void endLog() { - endXMLElement(); - } - - /** - * Prints a warning message to the log file. - * @param message the message, or null - * @param error an exception with a stack trace, or null - * @param status a status code, or null - */ - public void printWarning(String message, Throwable error, IStatus status) { - printAbort("warning", message, error, status); - } - - /** - * Called by the JUnit framework when an error occurs. - * @param test the test - * @param error the exception that occurred - */ - public void addError(Test test, Throwable error) { - printAbort("error", null, error, null); - super.addError(test, error); - } - - /** - * Called by the JUnit framework when an assertion failure occurs. - * @param test the test - * @param error the exception that occurred - */ - public void addFailure(Test test, AssertionFailedError error) { - printAbort("failure", null, error, null); - super.addFailure(test, error); - } - - /** - * Called by the JUnit framework to mark the beginning of a test case. - * @param test the test - */ - public void startTest(Test test) { - if (test instanceof TestCase) { - TestCase testCase = (TestCase) test; - startXMLElement("case", new String[] { "class", "name" }, - new String[] { testCase.getClass().getName(), testCase.getName() }); - groupStack.clear(); - currentTask = null; - } - super.startTest(test); - } - - /** - * Called by the JUnit framework to mark the end of a test case. - * @param test the test - */ - public void endTest(Test test) { - if (test instanceof TestCase) { - TestCase testCase = (TestCase) test; - if (currentTask != null) endTask(); - while (! groupStack.isEmpty()) endGroup(); - endXMLElement(); - } - super.endTest(test); - } - - /** - * Marks the beginning of a new task group. - * @param groupName the name for the group - */ - public void startGroup(String groupName) { - Assert.assertNull(currentTask); - startXMLElement("group", new String[] { "name" }, new String[] { groupName }); - groupStack.push(groupName); - } - - /** - * Marks the end of the active task group. - */ - public void endGroup() { - Assert.assertNull(currentTask); - Assert.assertTrue(! groupStack.empty()); - endXMLElement(); - groupStack.pop(); - } - - /** - * Marks the beginning of a new task. - * @param taskName the name for the task - */ - public void startTask(String taskName) { - Assert.assertNull(currentTask); - startXMLElement("task", new String[] { "name" }, new String[] { taskName }); - currentTask = new PerformanceTimer(taskName); - currentTask.start(); - } - - /** - * Marks the end of the active task. - */ - public void endTask() { - Assert.assertNotNull(currentTask); - currentTask.stop(); - printXMLElement("result", new String[] { "elapsed" }, - new String[] { Integer.toString(currentTask.getTotalMillis()) }); - endXMLElement(); - currentTask = null; - } - - protected void startXMLElement(String name, String[] attributes, String[] values) { - println(formatXMLElement(name, attributes, values, false)); - elements.push(name); - indent += " "; - } - - protected void printXMLElement(String name, String[] attributes, String[] values) { - println(formatXMLElement(name, attributes, values, true)); - } - - protected String formatXMLElement(String name, String[] attributes, String[] values, boolean quickEnd) { - // XXX need to escape certain characters in attribute values - StringBuffer buffer = new StringBuffer("<"); - buffer.append(name); - if (attributes != null && values != null) { - for (int i = 0; i < attributes.length; ++i) { - buffer.append(' '); - buffer.append(attributes[i]); - buffer.append("=\""); - buffer.append(values[i]); - buffer.append('"'); - } - } - if (quickEnd) buffer.append('/'); - buffer.append('>'); - return buffer.toString(); - } - - protected void endXMLElement() { - indent = indent.substring(2); - String name = (String) elements.pop(); - println("</" + name + ">"); - } - - protected void printXMLElementData(String line) { - // XXX need to escape certain characters in element data - println(line); - } - - protected void printAbort(String type, String message, Throwable error, IStatus status) { - if (status == null && error != null) { - if (error instanceof CoreException) { - status = ((CoreException) error).getStatus(); - } else if (error instanceof TeamException) { - status = ((TeamException) error).getStatus(); - } - } - if (message == null && error != null) { - message = error.getMessage(); - if (message == null) { - message = error.getClass().getName(); - } - } - if (message == null && status != null) { - message = status.getMessage(); - } - if (message == null) message = ""; - startXMLElement("abort", new String[] { "type", "message" }, - new String[] { type, message }); - if (status != null) printStatus(status); - if (error != null) printStackTrace(error); - endXMLElement(); - } - - protected void printStatus(IStatus status) { - startXMLElement("status", new String[] { "severity", "code", "plugin", "message" }, - new String[] { - Integer.toString(status.getSeverity()), - Integer.toString(status.getCode()), - status.getPlugin(), status.getMessage() }); - if (status.isMultiStatus()) { - IStatus[] children = status.getChildren(); - for (int i = 0; i < children.length; ++i) { - printStatus(children[i]); - } - } - endXMLElement(); - } - - protected void printStackTrace(Throwable error) { - // XXX need a better way to serialize the stack trace - String trace = BaseTestRunner.getFilteredTrace(error); - StringTokenizer tok = new StringTokenizer(trace, "\r\n"); - if (! tok.hasMoreTokens()) return; // empty trace? - tok.nextToken(); // skip message line - startXMLElement("trace", null, null); - while (tok.hasMoreTokens()) { - String frame = tok.nextToken(); - printXMLElementData(frame); - } - endXMLElement(); - } - - protected void println(String line) { - if (logStream != null) logStream.println(indent + line); - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/LoggingTestRunner.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/LoggingTestRunner.java deleted file mode 100644 index 9d2e5714b..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/LoggingTestRunner.java +++ /dev/null @@ -1,38 +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.tests.ccvs.ui.old; - - -import junit.framework.Test; -import junit.framework.TestResult; -import junit.textui.TestRunner; - -public class LoggingTestRunner extends TestRunner { - protected LoggingTestResult logResult; - - protected TestResult createTestResult() { - TestResult result = logResult; - logResult = null; - if (result == null) result = new LoggingTestResult(null); - return result; - } - - /** - * Runs a logging test suite. - * @param suite the test suite - * @param logResult the result object to use, or null to create a new one - * @param wait if true, pauses between test runs - */ - public void doRun(Test suite, LoggingTestResult logResult, boolean wait) { - this.logResult = logResult; - super.doRun(suite, wait); - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/MergeRunsVisitor.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/MergeRunsVisitor.java deleted file mode 100644 index 22b58dc46..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/MergeRunsVisitor.java +++ /dev/null @@ -1,76 +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.tests.ccvs.ui.old; - - -public class MergeRunsVisitor implements ILogEntryVisitor { - private RootEntry defaultRoot; - private RootEntry root; - private LogEntryContainer parent; - - /** - * Creates a new visitor to merge series of log entries. - * @param root the root of an existing log to merge into, or null - */ - public MergeRunsVisitor(RootEntry root) { - this.defaultRoot = root; - this.parent = null; - } - - /** - * Returns the root of the newly merged log, or null if none. - */ - public RootEntry getMergedRoot() { - return root; - } - - public void visitRootEntry(RootEntry entry) { - root = defaultRoot; - if (root == null) { - root = new RootEntry(null, entry.getName(), entry.getSDKBuildId(), entry.getTimestamp()); - } - parent = root; - entry.acceptChildren(this); - } - - public void visitCaseEntry(CaseEntry entry) { - LogEntryContainer oldParent = parent; - CaseEntry newEntry = (CaseEntry) parent.findMember(entry.getName(), CaseEntry.class); - if (newEntry == null) { - newEntry = new CaseEntry(parent, entry.getName(), entry.getClassName()); - } - parent = newEntry; - entry.acceptChildren(this); - parent = oldParent; - } - - public void visitGroupEntry(GroupEntry entry) { - LogEntryContainer oldParent = parent; - GroupEntry newEntry = (GroupEntry) parent.findMember(entry.getName(), GroupEntry.class); - if (newEntry == null) { - newEntry = new GroupEntry(parent, entry.getName()); - } - parent = newEntry; - entry.acceptChildren(this); - parent = oldParent; - } - - public void visitTaskEntry(TaskEntry entry) { - TaskEntry newEntry = (TaskEntry) parent.findMember(entry.getName(), TaskEntry.class); - if (newEntry == null) { - newEntry = new TaskEntry(parent, entry.getName()); - } - Result[] results = entry.getResults(); - for (int i = 0; i < results.length; i++) { - newEntry.addResult(results[i]); - } - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PerformanceTimer.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PerformanceTimer.java deleted file mode 100644 index ddf7a359e..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PerformanceTimer.java +++ /dev/null @@ -1,55 +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.tests.ccvs.ui.old; - - -public class PerformanceTimer { - private long startTime; - private int totalMillis; - private String name; - - /** - * Creates a timer, initially not running. - */ - public PerformanceTimer(String name) { - this.totalMillis = 0; - this.name = name; - } - - /** - * Starts the timer. Timer must not be running. - */ - public void start() { - startTime = System.currentTimeMillis(); - } - - /** - * Stops the timer. Timer must be running. - */ - public void stop() { - totalMillis += System.currentTimeMillis() - startTime; - startTime = 0; - } - - /** - * Returns the total number of milliseconds elapsed over all measured intervals. - */ - public int getTotalMillis() { - return totalMillis; - } - - /** - * Returns the name of this timer. - */ - public String getName() { - return name; - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintCSVDiffVisitor.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintCSVDiffVisitor.java deleted file mode 100644 index a05f9c0bb..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintCSVDiffVisitor.java +++ /dev/null @@ -1,102 +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.tests.ccvs.ui.old; - - -public class PrintCSVDiffVisitor extends PrintDiffVisitor { - private static final String GROUP_DELIMITER = " / "; - private DelimitedValuesWriter writer; - private String caseName; - private String groupName; - - /** - * Creates a diff visitor that generates CSV output. - * - * @param writer the delimited values writer - * @see PrintDiffVisitor - */ - public PrintCSVDiffVisitor(DelimitedValuesWriter writer, RootEntry olderRoot, int threshold, boolean ignoreNegligible) { - super(olderRoot, threshold, ignoreNegligible); - this.writer = writer; - } - - protected void visitRootEntry(RootEntry entry, RootEntry olderEntry) { - entry.acceptChildren(this); - } - - protected void visitCaseEntry(CaseEntry entry, CaseEntry olderEntry) { - caseName = entry.getName(); - groupName = null; - entry.acceptChildren(this); - } - - protected void visitGroupEntry(GroupEntry entry, GroupEntry olderEntry) { - String oldGroupName = groupName; - if (groupName == null) { - groupName = entry.getName(); - } else { - groupName += GROUP_DELIMITER + entry.getName(); - } - entry.acceptChildren(this); - groupName = oldGroupName; - } - - protected void visitTaskEntry(TaskEntry entry, TaskEntry olderEntry) { - writer.printFields(new String[] { - caseName, // case - groupName, // group - entry.getName() // task - }); - printTaskEntry(entry); - printTaskEntry(olderEntry); - if (entry.getTotalRuns() != 0 && olderEntry.getTotalRuns() != 0) { - int olderMean = olderEntry.getAverageMillis(); - int diff = entry.getAverageMillis() - olderMean; - if (isDifferenceUncertain(entry, olderEntry)) { - writer.printField("UNCERTAIN"); - } else if (isDifferenceNegligible(entry, olderEntry)) { - writer.printField("NEGLIGIBLE"); - } else { - writer.printField(diff > 0 ? "SLOWER" : "FASTER"); // change type - } - writer.printField(Integer.toString(Math.abs(diff))); // change - if (olderMean != 0) { - writer.printField(Util.formatPercentageRatio(Math.abs(diff), olderMean)); // % change - } else { - writer.printField(""); - } - } else { - writer.printFields(new String[] { "", "", "" }); - } - writer.endRecord(); - } - - protected void printTaskEntry(TaskEntry entry) { - if (entry.getTotalRuns() != 0) { - int mean = entry.getAverageMillis(); - writer.printFields(new String[] { - Integer.toString(entry.getTotalRuns()), // runs - Integer.toString(mean) // average - }); - if (entry.getTotalRuns() > 1 && mean != 0) { - int confidence = entry.getConfidenceInterval(); - writer.printFields(new String[] { - Integer.toString(confidence), // 95% confidence interval - Util.formatPercentageRatio(confidence, mean) // 95% c.i. as a percentage - }); - } else { - writer.printFields(new String[] { "", "" }); - } - } else { - writer.printFields(new String[] { "0", "", "", "" }); - } - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintCSVSummaryVisitor.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintCSVSummaryVisitor.java deleted file mode 100644 index 1bde78ace..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintCSVSummaryVisitor.java +++ /dev/null @@ -1,82 +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.tests.ccvs.ui.old; - - -public class PrintCSVSummaryVisitor implements ILogEntryVisitor { - private static final String GROUP_DELIMITER = " / "; - private DelimitedValuesWriter writer; - private String caseName; - private String groupName; - - /** - * Creates a visitor to print a log as comma-separated values. - * @param writer the delimited values writer - */ - public PrintCSVSummaryVisitor(DelimitedValuesWriter writer) { - this.writer = writer; - } - - public void visitRootEntry(RootEntry entry) { - entry.acceptChildren(this); - } - - public void visitCaseEntry(CaseEntry entry) { - caseName = entry.getName(); - groupName = null; - entry.acceptChildren(this); - } - - public void visitGroupEntry(GroupEntry entry) { - String oldGroupName = groupName; - if (groupName == null) { - groupName = entry.getName(); - } else { - groupName += GROUP_DELIMITER + entry.getName(); - } - entry.acceptChildren(this); - groupName = oldGroupName; - } - - public void visitTaskEntry(TaskEntry entry) { - writer.printFields(new String[] { - caseName, // case - groupName, // group - entry.getName() // task - }); - if (entry.getTotalRuns() != 0) { - int mean = entry.getAverageMillis(); - writer.printFields(new String[] { - Integer.toString(entry.getTotalRuns()), // runs - Integer.toString(mean) // average - }); - if (entry.getTotalRuns() > 1 && mean != 0) { - int confidence = entry.getConfidenceInterval(); - writer.printFields(new String[] { - Integer.toString(confidence), // 95% confidence interval - Util.formatPercentageRatio(confidence, mean) // 95% c.i. as a percentage - }); - } else { - writer.printFields(new String[] { "", "" }); - } - } else { - writer.printFields(new String[] { "0", "", "", "" }); - } - // append the result fields (ms) - Result[] results = entry.getResults(); - for (int i = 0; i < results.length; i++) { - Result result = results[i]; - if (result.getRuns() == 0) continue; - writer.printField(Integer.toString(result.getMillis() / result.getRuns())); - } - writer.endRecord(); - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintDiffMain.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintDiffMain.java deleted file mode 100644 index f4dfd60be..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintDiffMain.java +++ /dev/null @@ -1,154 +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.tests.ccvs.ui.old; - - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintStream; - -import org.xml.sax.SAXException; - -public class PrintDiffMain { - public static void main(String[] args) { - Parser parser = new Parser(); - if (! parser.parse(args)) { - System.err.println("Usage: <newer log> <older log> [-out <file>] [-csv] [-t <thresh>] [-i]"); - System.err.println(" -out <file> : specify the output file, default is console"); - System.err.println(" -csv : produce comma separated values data"); - System.err.println(" -t <thresh> : minimum non-negligible absolute % change"); - System.err.println(" -i : ignore negligible changes in results"); - return; - } - try { - PrintStream ps = System.out; - try { - if (parser.outputFile != null) ps = new PrintStream(new BufferedOutputStream(new FileOutputStream(parser.outputFile))); - printDiff(ps, parser.newerLogFile, parser.olderLogFile, parser.csv, parser.thresh, parser.ignore); - } finally { - if (ps != System.out) ps.close(); - } - } catch (Exception e) { - System.err.println("An error occurred:"); - e.printStackTrace(); - return; - } - } - - private static void printDiff(PrintStream ps, File newerLogFile, File olderLogFile, - boolean csv, int thresh, boolean ignore) throws IOException, SAXException { - // read and merge newer log - RootEntry newerRoot = LogEntry.readLog(newerLogFile); - MergeRunsVisitor mergeVisitor = new MergeRunsVisitor(null); - newerRoot.accept(mergeVisitor); - newerRoot = mergeVisitor.getMergedRoot(); - - // read and merge older log - RootEntry olderRoot = LogEntry.readLog(olderLogFile); - olderRoot.accept(mergeVisitor); - olderRoot = mergeVisitor.getMergedRoot(); - - // format options - StringBuffer options = new StringBuffer(); - if (thresh != 0) { - options.append("-t "); - options.append(Integer.toString(thresh)); - options.append(" "); - } - if (ignore) options.append("-i "); - - // format log file - if (csv) { - DelimitedValuesWriter writer = new DelimitedValuesWriter(ps, ",", true /*quoted*/); - // print header - writer.printRecord(new String[] { "", "Newer", "Older" }); - writer.printRecord(new String[] { "Log File", newerLogFile.toString(), olderLogFile.toString() }); - writer.printRecord(new String[] { "Generated", newerRoot.getTimestamp(), olderRoot.getTimestamp() }); - writer.printRecord(new String[] { "SDK Build", newerRoot.getSDKBuildId(), olderRoot.getSDKBuildId() }); - writer.endRecord(); - writer.printRecord(new String[] { "Options", "'" + options.toString() }); - writer.endRecord(); - writer.printRecord(new String[] { "", "", "", - "Newer", "", "", "", - "Older", "", "", "", - "", "", "" }); - writer.printRecord(new String[] { "Case", "Group", "Task", - "Runs", "Avg. (ms)", "95% C.I. (ms)", "95% C.I. (%)", - "Runs", "Avg. (ms)", "95% C.I. (ms)", "95% C.I. (%)", - "Change", "Diff (ms)", "Diff (%)" }); - // print quoted CSV data - PrintCSVDiffVisitor diffVisitor = new PrintCSVDiffVisitor(writer, olderRoot, thresh, ignore); - newerRoot.accept(diffVisitor); - } else { - // print header - ps.println("=== LOG DIFF ==="); - ps.println("Newer File: " + newerLogFile); - ps.println(" Generated: " + newerRoot.getTimestamp()); - ps.println(" SDK Build: " + newerRoot.getSDKBuildId()); - ps.println("Older File: " + olderLogFile); - ps.println(" Generated: " + olderRoot.getTimestamp()); - ps.println(" SDK Build: " + olderRoot.getSDKBuildId()); - ps.println("Options: " + options.toString()); - ps.println(); - // compute and print the differences - PrintTextDiffVisitor diffVisitor = new PrintTextDiffVisitor(ps, olderRoot, thresh, ignore); - newerRoot.accept(diffVisitor); - } - } - - private static class Parser extends ArgumentParser { - public File newerLogFile = null; - public File olderLogFile = null; - public File outputFile = null; - public boolean csv = false; - public int thresh = 0; - public boolean ignore = false; - - protected boolean handleFinished() { - return newerLogFile != null && olderLogFile != null; - } - protected boolean handleArgument(int index, String arg) { - if (index == 0) { - newerLogFile = new File(arg); - } else if (index == 1) { - olderLogFile = new File(arg); - } else { - return false; - } - return true; - } - protected boolean handleOption(String option, String arg) { - if ("-out".equals(option)) { - if (arg == null) return false; - outputFile = new File(arg); - } else if ("-csv".equals(option)) { - if (arg != null) return false; - csv = true; - } else if ("-t".equals(option)) { - if (arg == null) return false; - try { - thresh = Integer.parseInt(arg, 10); - } catch (NumberFormatException e) { - return false; - } - if (thresh < 0) return false; - } else if ("-i".equals(option)) { - if (arg != null) return false; - ignore = true; - } else { - return false; - } - return true; - } - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintDiffVisitor.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintDiffVisitor.java deleted file mode 100644 index ab2d2443e..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintDiffVisitor.java +++ /dev/null @@ -1,90 +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.tests.ccvs.ui.old; - - -public abstract class PrintDiffVisitor implements ILogEntryVisitor { - protected RootEntry olderRoot; - protected int threshold; // threshold for negligible changes - protected boolean ignoreNegligible; // if true, ignores negligible changes - protected LogEntryContainer olderParent; // corresponding parent in older root - - /** - * Creates a visitor to print a summary of the changes between a log - * and an older one. Optionally ignores differences within a certain threshold. - * Does not print older entries for which there are no corresponding newer ones. - * - * @param olderRoot the root of the older log - * @param threshold the minimum non-negligible % change - * @param ignoreNegligible if true, does not display negligible changes - */ - public PrintDiffVisitor(RootEntry olderRoot, int threshold, boolean ignoreNegligible) { - this.olderRoot = olderRoot; - this.olderParent = null; - this.threshold = threshold; - this.ignoreNegligible = ignoreNegligible; - } - - protected abstract void visitRootEntry(RootEntry entry, RootEntry olderEntry); - protected abstract void visitCaseEntry(CaseEntry entry, CaseEntry olderEntry); - protected abstract void visitGroupEntry(GroupEntry entry, GroupEntry olderEntry); - protected abstract void visitTaskEntry(TaskEntry entry, TaskEntry olderEntry); - - public void visitRootEntry(RootEntry entry) { - olderParent = olderRoot; - visitRootEntry(entry, olderRoot); - } - - public void visitCaseEntry(CaseEntry entry) { - LogEntryContainer prevOlderParent = olderParent; - if (olderParent != null) { - olderParent = (LogEntryContainer) olderParent.findMember(entry.getName(), CaseEntry.class); - } - visitCaseEntry(entry, (CaseEntry) olderParent); - olderParent = prevOlderParent; - } - - public void visitGroupEntry(GroupEntry entry) { - LogEntryContainer prevOlderParent = olderParent; - if (olderParent != null) { - olderParent = (LogEntryContainer) olderParent.findMember(entry.getName(), GroupEntry.class); - } - visitGroupEntry(entry, (GroupEntry) olderParent); - olderParent = prevOlderParent; - } - - public void visitTaskEntry(TaskEntry entry) { - TaskEntry olderEntry = null; - if (olderParent != null) { - olderEntry = (TaskEntry) olderParent.findMember(entry.getName(), TaskEntry.class); - } - if (ignoreNegligible && isDifferenceNegligible(entry, olderEntry)) return; - visitTaskEntry(entry, olderEntry); - } - - protected boolean isDifferenceNegligible(TaskEntry newerEntry, TaskEntry olderEntry) { - if (newerEntry.getTotalRuns() == 0 || olderEntry.getTotalRuns() == 0) return false; - int olderMean = olderEntry.getAverageMillis(); - if (olderMean == 0) return false; - int newerMean = newerEntry.getAverageMillis(); - int diff = Math.abs(newerMean - olderMean); - return diff * 100 / olderMean < threshold; - } - - protected boolean isDifferenceUncertain(TaskEntry newerEntry, TaskEntry olderEntry) { - if (newerEntry.getTotalRuns() == 0 || olderEntry.getTotalRuns() == 0) return false; - int olderMean = olderEntry.getAverageMillis(); - int newerMean = newerEntry.getAverageMillis(); - int diff = Math.abs(newerMean - olderMean); - int diffCI = newerEntry.getConfidenceInterval() + olderEntry.getConfidenceInterval(); - return diff < diffCI; - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintSummaryMain.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintSummaryMain.java deleted file mode 100644 index fbdf96960..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintSummaryMain.java +++ /dev/null @@ -1,122 +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.tests.ccvs.ui.old; - - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintStream; - -import org.xml.sax.SAXException; - -public class PrintSummaryMain { - public static void main(String[] args) { - Parser parser = new Parser(); - if (! parser.parse(args)) { - System.err.println("Usage: <log file> [-out <file>] [-csv] [-raw]"); - System.err.println(" -out <file> : specify the output file, default is console"); - System.err.println(" -csv : produce comma separated values data"); - System.err.println(" -raw : do not merge results from successive iterations"); - return; - } - try { - PrintStream ps = System.out; - try { - if (parser.outputFile != null) ps = new PrintStream(new BufferedOutputStream(new FileOutputStream(parser.outputFile))); - printLog(ps, parser.logFile, parser.csv, parser.raw); - } finally { - if (ps != System.out) ps.close(); - } - } catch (Exception e) { - System.err.println("An error occurred:"); - e.printStackTrace(); - return; - } - } - - private static void printLog(PrintStream ps, File logFile, boolean csv, boolean raw) - throws IOException, SAXException { - // read and merge the log - RootEntry root = LogEntry.readLog(logFile); - if (! raw) { - MergeRunsVisitor mergeVisitor = new MergeRunsVisitor(null); - root.accept(mergeVisitor); - root = mergeVisitor.getMergedRoot(); - } - - // format options - StringBuffer options = new StringBuffer(); - if (raw) options.append("-raw "); - - // format log file - if (csv) { - DelimitedValuesWriter writer = new DelimitedValuesWriter(ps, ",", true /*quoted*/); - // print header - writer.printRecord(new String[] { "Log File", logFile.toString() }); - writer.printRecord(new String[] { "Generated", root.getTimestamp() }); - writer.printRecord(new String[] { "SDK Build", root.getSDKBuildId() }); - writer.endRecord(); - writer.printRecord(new String[] { "Options", "'" + options.toString() }); - writer.endRecord(); - writer.printRecord(new String[] { "Case", "Group", "Task", - "Runs", "Avg. (ms)", "95% C.I. (ms)", "95% C.I. (%)", "Results (ms)" }); - // print quoted CSV data - PrintCSVSummaryVisitor visitor = new PrintCSVSummaryVisitor(writer); - root.accept(visitor); - } else { - // print header - ps.println("=== LOG SUMMARY ==="); - ps.println("File: " + logFile); - ps.println(" Generated: " + root.getTimestamp()); - ps.println(" SDK Build: " + root.getSDKBuildId()); - ps.println("Options: " + options.toString()); - ps.println(); - // print the log summary - root.accept(new PrintTextSummaryVisitor(ps)); - } - } - - private static class Parser extends ArgumentParser { - public File logFile = null; - public File outputFile = null; - public boolean csv = false; - public boolean raw = false; - - protected boolean handleFinished() { - return logFile != null; - } - protected boolean handleArgument(int index, String arg) { - if (index == 0) { - logFile = new File(arg); - } else { - return false; - } - return true; - } - protected boolean handleOption(String option, String arg) { - if ("-out".equals(option)) { - if (arg == null) return false; - outputFile = new File(arg); - } else if ("-csv".equals(option)) { - if (arg != null) return false; - csv = true; - } else if ("-raw".equals(option)) { - if (arg != null) return false; - raw = true; - } else { - return false; - } - return true; - } - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintTextDiffVisitor.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintTextDiffVisitor.java deleted file mode 100644 index 4572a8734..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintTextDiffVisitor.java +++ /dev/null @@ -1,147 +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.tests.ccvs.ui.old; - - -import java.io.PrintStream; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -public class PrintTextDiffVisitor extends PrintDiffVisitor { - private PrintStream os; - private List diffText; // list of things to print - private String indent; - - /** - * Creates a diff visitor that generates text output. - * - * @param os the output stream - * @see PrintDiffVisitor - */ - public PrintTextDiffVisitor(PrintStream os, RootEntry olderRoot, int threshold, boolean ignoreNegligible) { - super(olderRoot, threshold, ignoreNegligible); - this.os = os; - this.diffText = null; - this.indent = ""; - } - - protected void visitRootEntry(RootEntry entry, RootEntry olderEntry) { - entry.acceptChildren(this); - } - - protected void visitCaseEntry(CaseEntry entry, CaseEntry olderEntry) { - String oldIndent = indent; - indent += " "; - StringBuffer line = new StringBuffer(indent); - line.append("%%% "); - line.append(entry.getName()); - line.append(", class="); - line.append(entry.getClassName()); - line.append(':'); - os.println(line); - diffText = null; - entry.acceptChildren(this); - if (diffText != null) { - Iterator it = diffText.iterator(); - while (it.hasNext()) os.println((String) it.next()); - } - diffText = null; - os.println(); - indent = oldIndent; - } - - protected void visitGroupEntry(GroupEntry entry, GroupEntry olderEntry) { - String oldIndent = indent; - List oldDiffText = diffText; - indent += " "; - diffText = null; - entry.acceptChildren(this); - indent = oldIndent; - if (diffText != null) { - StringBuffer line = new StringBuffer(indent); - line.append("+ "); - line.append(entry.getName()); - line.append(':'); - diffText.add(0, line.toString()); - if (oldDiffText != null) diffText.addAll(0, oldDiffText); - } else { - diffText = oldDiffText; - } - } - - protected void visitTaskEntry(TaskEntry entry, TaskEntry olderEntry) { - // print task description - if (diffText == null) diffText = new LinkedList(); // using a list for speedy prepending - StringBuffer line = new StringBuffer(indent); - line.append("- "); - line.append(entry.getName()); - line.append(": "); - diffText.add(line.toString()); - - // print new entry performance - printTaskEntry(" newer: ", entry); - - // print older entry performance - if (olderEntry == null) return; - printTaskEntry(" older: ", olderEntry); - - // print difference - if (entry.getTotalRuns() == 0 || olderEntry.getTotalRuns() == 0) return; - int olderMean = olderEntry.getAverageMillis(); - int diff = entry.getAverageMillis() - olderMean; - line = new StringBuffer(indent); - line.append(" diff : "); - - if (isDifferenceUncertain(entry, olderEntry)) { - line.append("UNCERTAIN"); - } else if (isDifferenceNegligible(entry, olderEntry)) { - line.append("NEGLIGIBLE"); - } else { - line.append(diff > 0 ? "SLOWER" : "FASTER"); - line.append(" by "); - line.append(Integer.toString(Math.abs(diff))); - line.append(" ms"); - if (olderEntry.getAverageMillis() != 0) { - line.append(" = "); - line.append(Util.formatPercentageRatio(Math.abs(diff), olderMean)); - } - line.append(" avg."); - } - diffText.add(line.toString()); - } - - protected void printTaskEntry(String prefix, TaskEntry task) { - StringBuffer line = new StringBuffer(indent); - line.append(prefix); - if (task.getTotalRuns() != 0) { - int averageTime = task.getAverageMillis(); - line.append(Integer.toString(averageTime)); - line.append(" ms"); - if (task.getTotalRuns() > 1) { - line.append(" avg. over "); - line.append(Integer.toString(task.getTotalRuns())); - line.append(" runs"); - if (averageTime != 0) { - int confidence = task.getConfidenceInterval(); - line.append(" (95% C.I. +/- "); - line.append(Integer.toString(confidence)); - line.append(" ms = "); - line.append(Util.formatPercentageRatio(confidence, averageTime)); - line.append(")"); - } - } - } else { - line.append("skipped!"); - } - diffText.add(line.toString()); - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintTextSummaryVisitor.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintTextSummaryVisitor.java deleted file mode 100644 index a2d91ab06..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/PrintTextSummaryVisitor.java +++ /dev/null @@ -1,109 +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.tests.ccvs.ui.old; - - -import java.io.PrintStream; - -public class PrintTextSummaryVisitor implements ILogEntryVisitor { - private PrintStream os; - private String indent; - private int totalAverageTime; - - /** - * Creates a visitor to print a summary of all entries contained in a log. - * @param os the output stream - */ - public PrintTextSummaryVisitor(PrintStream os) { - this.os = os; - this.indent = ""; - this.totalAverageTime = 0; - } - - protected void visitContainer(LogEntryContainer container) { - int oldTotalAverageTime = totalAverageTime; - indent += " "; - container.acceptChildren(this); - int averageTime = totalAverageTime - oldTotalAverageTime; - StringBuffer line = new StringBuffer(indent); - line.append("* total: "); - line.append(Integer.toString(averageTime)); - line.append(" ms"); - os.println(line); - indent = indent.substring(2); - } - - /** - * Prints the root entry information. - */ - public void visitRootEntry(RootEntry entry) { - entry.acceptChildren(this); - } - - /** - * Prints the total average time spent by all subgroups and subtasks. - */ - public void visitCaseEntry(CaseEntry entry) { - StringBuffer line = new StringBuffer(indent); - line.append("%%% "); - line.append(entry.getName()); - line.append(", class="); - line.append(entry.getClassName()); - line.append(':'); - os.println(line); - visitContainer(entry); - os.println(); - } - - /** - * Prints the total average time spent by all subtasks. - */ - public void visitGroupEntry(GroupEntry entry) { - StringBuffer line = new StringBuffer(indent); - line.append("+ "); - line.append(entry.getName()); - line.append(':'); - os.println(line); - visitContainer(entry); - } - - /** - * Prints the average amount of time spent by a task. - */ - public void visitTaskEntry(TaskEntry task) { - StringBuffer line = new StringBuffer(indent); - line.append("- "); - line.append(task.getName()); - line.append(": "); - if (task.getTotalRuns() != 0) { - int averageTime = task.getAverageMillis(); - totalAverageTime += averageTime; - line.append(Integer.toString(averageTime)); - line.append(" ms"); - if (task.getTotalRuns() > 1) { - line.append(" avg. over "); - line.append(Integer.toString(task.getTotalRuns())); - line.append(" runs"); - if (averageTime != 0) { - int confidence = task.getConfidenceInterval(); - line.append(" (95% C.I. +/- "); - line.append(Integer.toString(confidence)); - line.append(" ms = "); - line.append(Util.formatPercentageRatio(confidence, averageTime)); - line.append(")"); - } - } - } else { - line.append("skipped!"); - } - os.println(line); - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/Result.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/Result.java deleted file mode 100644 index 0755d5e70..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/Result.java +++ /dev/null @@ -1,39 +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.tests.ccvs.ui.old; - - -import org.xml.sax.Attributes; - -/** - * Holds the result of one iteration of tests. - * Note that a test might be run multiple times per iteration, particularly if it - * is of very short duration to reduce sampling error. This behaviour is not supported - * at this time, but will likely be of value in the future. - */ -public class Result { - private int runs; - private int millis; - - public Result(Attributes attributes) { - this(1, Integer.parseInt(attributes.getValue("elapsed"))); - } - public Result(int runs, int millis) { - this.runs = runs; - this.millis = millis; - } - public int getRuns() { - return runs; - } - public int getMillis() { - return millis; - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/RootEntry.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/RootEntry.java deleted file mode 100644 index 1d1452eb2..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/RootEntry.java +++ /dev/null @@ -1,48 +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.tests.ccvs.ui.old; - - -import org.xml.sax.Attributes; - -public class RootEntry extends LogEntryContainer { - private String sdkBuildId; - private String timestamp; - - public RootEntry(LogEntryContainer parent, Attributes attributes) { - this(parent, attributes.getValue("name"), - attributes.getValue("sdkbuild"), attributes.getValue("timestamp")); - } - - public RootEntry(LogEntryContainer parent, String name, String sdkBuildId, String timestamp) { - super(parent, name); - this.sdkBuildId = (sdkBuildId != null) ? sdkBuildId : "unknown"; - this.timestamp = (timestamp != null) ? timestamp : "unknown"; - } - - public void accept(ILogEntryVisitor visitor) { - visitor.visitRootEntry(this); - } - - /** - * Returns the SDK Build id. - */ - public String getSDKBuildId() { - return sdkBuildId; - } - - /** - * Returns the class name of the test case. - */ - public String getTimestamp() { - return timestamp; - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/SequenceGenerator.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/SequenceGenerator.java deleted file mode 100644 index 1b76b1a63..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/SequenceGenerator.java +++ /dev/null @@ -1,63 +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.tests.ccvs.ui.old; - - -import java.util.Random; - -/** - * Encapsulates algorithms and state for generating deterministic sequences. - * The sequence of numbers generated will always follow the same pattern, - * regardless of the time, place, or platform. - */ -public class SequenceGenerator { - private static long globalSeqNum = System.currentTimeMillis() * 1000; - private final Random random; - private int uniqueInt; - - /** - * Constructs a new sequence generator with a known seed. - */ - public SequenceGenerator() { - random = new Random(3141592653589793238L); // a known constant - uniqueInt = 1000000; - } - - /** - * Returns a globally unique long integer. - */ - public static long nextGloballyUniqueLong() { - return globalSeqNum++; - } - - /** - * Returns a unique 7-digit integer. - */ - public int nextUniqueInt() { - return uniqueInt++; - } - - /** - * Returns a pseudo-random integer between 0 and n-1. - * @see Random#nextInt(int) - */ - public int nextInt(int n) { - return random.nextInt(n); - } - - /** - * Returns a pseudo-random real number following a gaussian distribution. - * @see Random#nextGaussian() - */ - public double nextGaussian() { - return random.nextGaussian(); - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/SyncTests.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/SyncTests.java deleted file mode 100644 index a74b46604..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/SyncTests.java +++ /dev/null @@ -1,112 +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.tests.ccvs.ui.old; - - -import junit.framework.Test; -import junit.framework.TestSuite; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.team.internal.ccvs.core.CVSTag; - -public class SyncTests extends CVSUITestCase { - private static final int FILE_SIZE_MEAN = 16384; - private static final int FILE_SIZE_VARIANCE = 0; - private static final int PROB_BINARY = 0; - - public SyncTests(Test test) { - super(test); - } - - public static Test suite() { - return new BenchmarkTestSetup(new TestSuite(SyncTests.class)); - } - - public void testSync0() throws Exception { - // test sync on project with no changes - IProject project = setupOutProject(); - startGroup("test sync with no changes"); - syncCommitResources(new IResource[] { project }, null, ""); - endGroup(); - } - - public void testSync1() throws Exception { - runTestSync(1); - } - - public void testSync10() throws Exception { - runTestSync(10); - } - - public void testSync100() throws Exception { - runTestSync(100); - } - - protected IProject setupOutProject() throws Exception { - IProject project = createAndImportProject("testSync", BenchmarkTestSetup.SMALL_ZIP_FILE); - disableLog(); - actionShareProject(project); - syncCommitResources(new IResource[] { project }, null, "initial"); - enableLog(); - return project; - } - - /** - * Runs a sequence of operations for the synchronizer tests. - * A parallel project is used to generate incoming changes. - */ - protected void runTestSync(int size) throws Exception { - final SequenceGenerator gen = new SequenceGenerator(); - - // setup out project then move it out of the way - IProject outProject = setupOutProject(); - String moduleName = outProject.getName(); - Utils.renameResource(outProject, moduleName + "out"); - outProject = Utils.getProject(moduleName + "out"); - - // setup in project - disableLog(); - actionCheckoutProjects(new String[] { moduleName }, new CVSTag[] { new CVSTag() }); - enableLog(); - IProject inProject = Utils.getProject(moduleName); - - /*** outgoing and incoming changes ***/ - startGroup("synchronize " + size + " added file(s)"); - Utils.createRandomDeepFiles(gen, outProject, size, FILE_SIZE_MEAN, FILE_SIZE_VARIANCE, PROB_BINARY); - startGroup("as outgoing changes"); - syncCommitResources(new IResource[] { outProject }, null, ""); - endGroup(); - startGroup("as incoming changes"); - syncUpdateResources(new IResource[] { inProject }, null); - endGroup(); - endGroup(); - - startGroup("synchronize " + size + " modified file(s)"); - Utils.modifyRandomDeepFiles(gen, outProject, size); - startGroup("as outgoing changes"); - syncCommitResources(new IResource[] { outProject }, null, ""); - endGroup(); - startGroup("as incoming changes"); - syncUpdateResources(new IResource[] { inProject }, null); - endGroup(); - endGroup(); - - startGroup("synchronize " + size + " removed file(s)"); - Utils.deleteRandomDeepFiles(gen, outProject, size); - startGroup("as outgoing changes"); - syncCommitResources(new IResource[] { outProject }, null, ""); - endGroup(); - startGroup("as incoming changes"); - syncUpdateResources(new IResource[] { inProject }, null); - endGroup(); - endGroup(); - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/TaskEntry.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/TaskEntry.java deleted file mode 100644 index 666b40914..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/TaskEntry.java +++ /dev/null @@ -1,106 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.tests.ccvs.ui.old; - - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.xml.sax.Attributes; - -public class TaskEntry extends LogEntry { - private List /* of Result */ results = new ArrayList(); - - public TaskEntry(LogEntryContainer parent, Attributes attributes) { - this(parent, attributes.getValue("name")); - } - - public TaskEntry(LogEntryContainer parent, String name) { - super(parent, name); - } - - public void accept(ILogEntryVisitor visitor) { - visitor.visitTaskEntry(this); - } - - /** - * Returns the average number of milliseconds elapsed, or -1 if unknown. - */ - public int getAverageMillis() { - int totalMillis = 0; - int totalRuns = 0; - for (Iterator it = results.iterator(); it.hasNext();) { - Result result = (Result) it.next(); - totalMillis += result.getMillis(); - totalRuns += result.getRuns(); - } - if (totalRuns == 0) return -1; - return totalMillis / totalRuns; - } - - /** - * Returns the standard deviation of the sample. - * sqrt((n * sum(X^2) - sum(X)^2) / (n * (n-1))) - */ - public double getStandardDeviation() { - double sumOfSquares = 0.0, sum = 0.0; - int totalRuns = 0; - for (Iterator it = results.iterator(); it.hasNext();) { - Result result = (Result) it.next(); - if (result.getRuns() == 0) continue; - totalRuns += result.getRuns(); - sum += result.getMillis(); - double average = (double)result.getMillis() / result.getRuns(); - sumOfSquares += average * average * result.getRuns(); - } - if (totalRuns == 0) return 0; - return Math.sqrt((sumOfSquares * totalRuns - sum * sum) / (totalRuns * (totalRuns - 1))); - } - - /** - * Returns a 95% confidence interval from the mean represented by getAverageMillis() - * Uses the formula: - * 1.960 * stdev() / sqrt(n) - */ - public int getConfidenceInterval() { - return (int) (1.960 * getStandardDeviation() / Math.sqrt(getTotalRuns())); - } - - /** - * Returns the number of times this task was run. - */ - public int getTotalRuns() { - int totalRuns = 0; - for (Iterator it = results.iterator(); it.hasNext();) { - Result result = (Result) it.next(); - totalRuns += result.getRuns(); - } - return totalRuns; - } - - /** - * Returns an array of all Results for this task. - */ - public Result[] getResults() { - return (Result[]) results.toArray(new Result[results.size()]); - } - - /** - * Adds a result. - * @param result the result - */ - public void addResult(Result result) { - results.add(result); - } - - -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/Util.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/Util.java deleted file mode 100644 index ac0f2bd75..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/Util.java +++ /dev/null @@ -1,23 +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.tests.ccvs.ui.old; - - -import java.text.DecimalFormat; -import java.text.NumberFormat; - -public class Util { - private static final NumberFormat percentageFormat = new DecimalFormat("####0.00%"); - - public static String formatPercentageRatio(int numerator, int denominator) { - return percentageFormat.format((double)numerator / denominator); - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/Utils.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/Utils.java deleted file mode 100644 index 4ef55baba..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/Utils.java +++ /dev/null @@ -1,774 +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.tests.ccvs.ui.old; - - -import java.io.*; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.*; -import java.util.List; -import java.util.zip.ZipException; -import java.util.zip.ZipFile; - -import junit.framework.Assert; - -import org.eclipse.compare.structuremergeviewer.*; -import org.eclipse.core.resources.*; -import org.eclipse.core.runtime.*; -import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.jface.wizard.IWizard; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.*; -import org.eclipse.team.internal.ccvs.core.CVSStatus; -import org.eclipse.ui.internal.ide.dialogs.InternalErrorDialog; -import org.eclipse.ui.wizards.datatransfer.ImportOperation; -import org.eclipse.ui.wizards.datatransfer.ZipFileStructureProvider; - -/** - * Provides helpers for: - * <ul> - * <li>Resource manipulation</li> - * <li>Diff trees</li> - * <li>UI automation</li> - * <li>Parallel development simulation</li> - * </ul> - * - * Note: This class is referenced from the VCM 1.0 performance tests. - */ -public class Utils { - /*** RESOURCE MANIPULATION SUPPORT ***/ - - /** - * Gets a handle for a project of a given name. - * @param name the project name - * @return the project handle - */ - public static IProject getProject(String name) throws CoreException { - return ResourcesPlugin.getWorkspace().getRoot().getProject(name); - } - - /** - * Creates a new project. - * @param name the project name - * @return the project handle - */ - public static IProject createProject(String name) throws CoreException { - IProject project = getProject(name); - if (!project.exists()) project.create(null); - if (!project.isOpen()) project.open(null); - return project; - } - - /** - * Deletes a project. - * @param project the project - */ - public static void deleteProject(IProject project) throws CoreException { - project.delete(false /*force*/, null); - } - - /** - * Deletes a file and prunes empty containing folders. - * @param file the file to delete - */ - public static void deleteFileAndPrune(IFile file) throws CoreException { - file.delete(false /*force*/, null); - IContainer container = file.getParent(); - while (container != null && container instanceof IFolder && - isFolderEmpty((IFolder) container)) { - deleteFolder((IFolder) container); - container = container.getParent(); - } - } - - /** - * Deletes a folder. - */ - public static void deleteFolder(IFolder folder) throws CoreException { - try { - folder.delete(false /*force*/, null); - } catch (CoreException e) { - IStatus status = e.getStatus(); - // ignore errors caused by attempting to delete folders that CVS needs to have around - if (findStatusByCode(status, CVSStatus.FOLDER_NEEDED_FOR_FILE_DELETIONS) == null) { - throw e; - } - } - } - - /** - * Finds an IStatus instance in a multi-status by status code. - */ - public static IStatus findStatusByCode(IStatus status, int code) { - if (status.getCode() == code) return status; - IStatus[] children = status.getChildren(); - for (int i = 0; i < children.length; i++) { - IStatus found = findStatusByCode(children[i], code); - if (found != null) return found; - } - return null; - } - - /** - * Creates a uniquely named project. - * @param prefix a string prepended to the generated name - * @return the new project - */ - public static IProject createUniqueProject(String prefix) throws CoreException { - return createProject(makeUniqueName(null, prefix, null)); - } - - /** - * Creates a uniquely named file in the parent folder or project with random contents. - * @param gen the sequence generator - * @param parent the parent IFolder or IProject for the new file - * @param meanSize the mean size of file to create (in bytes) - * @param variance 69% of files with be within this amount of the mean - * @param probBinary the probability of a new file being binary as a percentage - * @return the new file - */ - public static IFile createUniqueFile(SequenceGenerator gen, IContainer parent, - int meanSize, int variance, int probBinary) throws IOException, CoreException { - int fileSize; - do { - fileSize = (int) Math.abs(gen.nextGaussian() * variance + meanSize); - } while (fileSize > meanSize + variance * 4); // avoid huge files - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - String fileName; - if (gen.nextInt(100) < probBinary) { - fileName = makeUniqueName(gen, "file", "class"); // binary - writeRandomBytes(gen, os, fileSize); - } else { - fileName = makeUniqueName(gen, "file", "txt"); // text - writeRandomText(gen, os, fileSize); - } - IFile file = parent.getFile(new Path(fileName)); - file.create(new ByteArrayInputStream(os.toByteArray()), true, null); - os.close(); - return file; - } - - /** - * Creates a uniquely named folder in the parent folder. - * @param gen the sequence generator - * @param parent the parent IFolder or IProject for the new folder - * @return the new folder - */ - public static IFolder createUniqueFolder(SequenceGenerator gen, IContainer parent) throws CoreException { - IFolder folder = parent.getFolder(new Path(Utils.makeUniqueName(gen, "folder", null))); - folder.create(false /*force*/, true /*local*/, null); - return folder; - } - - /** - * Renames a resource. - * The resource handle becomes invalid. - * @param resource the existing resource - * @param newName the new name for the resource - */ - public static void renameResource(IResource resource, String newName) throws CoreException { - switch (resource.getType()) { - case IResource.PROJECT: { - IProject project = (IProject) resource; - IProjectDescription desc = project.getDescription(); - desc.setName(newName); - project.move(desc, false /*force*/, true /*keepHistory*/, null); - } break; - case IResource.FOLDER: { - try { - resource.move(new Path(newName), false /*force*/, null); - } catch (CoreException e) { - IStatus status = e.getStatus(); - // ignore errors caused by attempting to delete folders that CVS needs to have around - if (findStatusByCode(status, CVSStatus.FOLDER_NEEDED_FOR_FILE_DELETIONS) == null) { - throw e; - } - } - } break; - default: - resource.move(new Path(newName), false /*force*/, null); - break; - } - } - - /** - * Modified a resource. - * @param gen the sequence generator - * @param file the file to modify - */ - public static void modifyFile(SequenceGenerator gen, IFile file) - throws IOException, CoreException { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - try { - InputStream is = file.getContents(true); - try { - byte[] buffer = new byte[8192]; - int rsize; - boolean changed = false; - while ((rsize = is.read(buffer)) != -1) { - double gaussian; - do { - gaussian = gen.nextGaussian() * 0.5; // large changes are less likely than small ones - } while (gaussian > 1.0 || gaussian < -1.0); - int changeSize = (int) (gaussian * rsize); - changed = changed || changeSize != 0; - os.write(buffer, 0, changeSize < 0 ? - changeSize : rsize); // shrink file - writeRandomText(gen, os, changeSize); // enlarge file - } - if (! changed) os.write('!'); // make sure we actually did change the file - file.setContents(new ByteArrayInputStream(os.toByteArray()), false /*force*/, true /*keepHistory*/, null); - } finally { - is.close(); - } - } finally { - os.close(); - } - } - - /** - * Creates a unique name. - * Ensures that a deterministic sequence of names is generated for all files - * and folders within a project, though not across sessions. - * - * @param gen the generator, or null if this name is to be globally unique - * @param prefix a string prepended to the generated name - * @param extension the file extension not including the period, null if none - * @return the new name - */ - public static String makeUniqueName(SequenceGenerator gen, String prefix, String extension) - throws CoreException { - StringBuffer name = new StringBuffer(prefix); - name.append('-'); - if (gen == null) { - name.append(SequenceGenerator.nextGloballyUniqueLong()); - } else { - name.append(gen.nextUniqueInt()); - } - if (extension != null) { - name.append('.'); - name.append(extension); - } - return name.toString(); - } - - /** - * Imports a .zip file into a container's root folder. - * @param container the container - * @param file the path of the .zip file - */ - public static void importZip(IContainer container, File file) - throws IOException, ZipException, InterruptedException, InvocationTargetException { - ZipFile zipFile = new ZipFile(file); - ZipFileStructureProvider provider = new ZipFileStructureProvider(zipFile); - ImportOperation importOperation = new ImportOperation(container.getFullPath(), - provider.getRoot(), provider, null); - importOperation.setOverwriteResources(true); // don't ask - importOperation.run(new NullProgressMonitor()); - Assert.assertTrue(importOperation.getStatus().isOK()); - } - - /** - * Writes random text to an output stream. - * @param gen the sequence generator - */ - public static void writeRandomText(SequenceGenerator gen, OutputStream os, int count) throws IOException { - while (count-- > 0) { - int c = gen.nextInt(99); - os.write((c >= 95) ? '\n' : c + ' '); - } - } - - /** - * Writes random bytes to an output stream. - * @param gen the sequence generator - */ - public static void writeRandomBytes(SequenceGenerator gen, OutputStream os, int count) throws IOException { - while (count-- > 0) { - os.write(gen.nextInt(256)); - } - } - - /** - * Creates a random folder deeply below the root folder. - * @param gen the sequence generator - * @param root the root IFolder or IProject for the operation - * @return the new folder - */ - public static IFolder createRandomDeepFolder(SequenceGenerator gen, IContainer root) throws CoreException { - IContainer container = pickRandomDeepContainer(gen, root); - for (;;) { - IFolder folder = createUniqueFolder(gen, container); - container = folder; - // 12.5% chance of creating a nested folder - if (gen.nextInt(8) != 0) return folder; - } - } - - /** - * Creates several random files deeply below the root folder. - * @param gen the sequence generator - * @param root the root IFolder or IProject for the operation - * @param count the number of files to create - * @param meanSize the mean size of file to create (in bytes) - * @param probBinary the probability of a new file being binary as a percentage - */ - public static void createRandomDeepFiles(SequenceGenerator gen, IContainer root, int count, - int meanSize, int variance, int probBinary) throws IOException, CoreException { - while (count-- > 0) { - createUniqueFile(gen, pickRandomDeepContainer(gen, root), meanSize, variance, probBinary); - } - } - - /** - * Deletes several random files deeply below the root folder. - * @param gen the sequence generator - * @param root the root IFolder or IProject for the operation - * @param count the number of files to delete - */ - public static void deleteRandomDeepFiles(SequenceGenerator gen, IContainer root, int count) throws CoreException { - while (count-- > 0) { - IFile file = pickRandomDeepFile(gen, root); - if (file == null) break; - deleteFileAndPrune(file); - } - } - - /** - * Modifies several random files deeply below the root folder. - * @param gen the sequence generator - * @param root the root IFolder or IProject for the operation - * @param count the number of files to modify - */ - public static void modifyRandomDeepFiles(SequenceGenerator gen, IContainer root, int count) - throws IOException, CoreException { - // perhaps we can add a parameter for the "magnitude" of the change - while (count-- > 0) { - IFile file = pickRandomDeepFile(gen, root); - if (file == null) break; - modifyFile(gen, file); - } - } - - /** - * Touches several random files deeply below the root folder. - * @param gen the sequence generator - * @param root the root IFolder or IProject for the operation - * @param count the number of files to touch - */ - public static void touchRandomDeepFiles(SequenceGenerator gen, IContainer root, int count) throws CoreException { - while (count-- > 0) { - IFile file = pickRandomDeepFile(gen, root); - if (file == null) break; - file.touch(null); - } - } - - /** - * Renames several random files deeply below the root folder. - * @param gen the sequence generator - * @param root the root IFolder or IProject for the operation - * @param count the number of files to touch - */ - public static void renameRandomDeepFiles(SequenceGenerator gen, IContainer root, int count) throws CoreException { - IProject project = root.getProject(); - while (count-- > 0) { - IFile file = pickRandomDeepFile(gen, root); - if (file == null) break; - renameResource(file, makeUniqueName(gen, "file", file.getFileExtension())); - } - } - - /** - * Picks a random file from the parent folder or project. - * @param gen the sequence generator - * @param parent the parent IFolder or IProject for the operation - * @return the file that was chosen, or null if no suitable files - */ - public static IFile pickRandomFile(SequenceGenerator gen, IContainer parent) throws CoreException { - IResource[] members = filterResources(parent.members()); - for (int size = members.length; size != 0; --size) { - int elem = gen.nextInt(size); - if (members[elem] instanceof IFile) return (IFile) members[elem]; - System.arraycopy(members, elem + 1, members, elem, size - elem - 1); - } - return null; - } - - /** - * Picks a random folder from the parent folder or project. - * @param gen the sequence generator - * @param parent the parent IFolder or IProject for the operation - * @return the folder, or null if no suitable folders - */ - public static IFolder pickRandomFolder(SequenceGenerator gen, IContainer parent) throws CoreException { - IResource[] members = filterResources(parent.members()); - for (int size = members.length; size != 0; --size) { - int elem = gen.nextInt(size); - if (members[elem] instanceof IFolder) return (IFolder) members[elem]; - System.arraycopy(members, elem + 1, members, elem, size - elem - 1); - } - return null; - } - - /** - * Picks a random file deeply from the root folder or project. - * @param gen the sequence generator - * @param root the root IFolder or IProject for the operation - * @return the file that was chosen, or null if no suitable files - */ - public static IFile pickRandomDeepFile(SequenceGenerator gen, IContainer root) throws CoreException { - IResource[] members = filterResources(root.members()); - for (int size = members.length; size != 0; --size) { - int elem = gen.nextInt(size); - IResource resource = members[elem]; - if (resource instanceof IFile) return (IFile) resource; - if (resource instanceof IFolder) { - IFile file = pickRandomDeepFile(gen, (IFolder) resource); - if (file != null) return file; - } - System.arraycopy(members, elem + 1, members, elem, size - elem - 1); - } - return null; - } - - /** - * Picks a random folder deeply from the root folder or project. - * May pick the project's root container. - * @param gen the sequence generator - * @param root the root IFolder or IProject for the operation - * @return the container that was chosen, never null - */ - public static IContainer pickRandomDeepContainer(SequenceGenerator gen, IContainer root) throws CoreException { - if (gen.nextInt(6) == 0) { - IResource[] members = filterResources(root.members()); - for (int size = members.length; size != 0; --size) { - int elem = gen.nextInt(size); - IResource resource = members[elem]; - if (resource instanceof IFolder) { - return pickRandomDeepContainer(gen, (IFolder) resource); - } - System.arraycopy(members, elem + 1, members, elem, size - elem - 1); - } - } - Assert.assertTrue(isValidContainer(root)); - return root; - } - - /** - * Returns true if the folder does not contain any real files. - */ - public static boolean isFolderEmpty(IFolder folder) throws CoreException { - IResource[] members = folder.members(); - for (int i = 0; i < members.length; ++i) { - if (isValidFile(members[i]) || isValidFolder(members[i])) return false; - } - return true; - } - - /** - * Returns true iff file is a valid IFile (that should not be ignored). - */ - public static boolean isValidFile(IResource file) throws CoreException { - String name = file.getName(); - return file instanceof IFile - && ! file.isPhantom() - && ! name.equals(".classpath") - && ! name.equals(".project") - && ! name.equals(".vcm_meta"); - } - - /** - * Returns true iff folder is a valid IFolder (that should not be ignored). - */ - public static boolean isValidFolder(IResource folder) throws CoreException { - String name = folder.getName(); - return folder instanceof IFolder - && ! folder.isPhantom() - && ! name.equals("CVS") - && ! name.equals("bin"); - } - - /** - * Returns true iff container is a valid IFolder or IProject (that should not be ignored). - */ - public static boolean isValidContainer(IResource container) throws CoreException { - return container instanceof IProject || isValidFolder(container); - } - - /** - * Returns true iff resource is a valid IFile, IFolder or IProject (that should not be ignored). - */ - public static boolean isValidResource(IResource resource) throws CoreException { - return isValidFile(resource) || isValidContainer(resource); - } - - /** - * Filters and sorts an array of resources to ensure deterministic behaviour across - * sessions. The general idea is to guarantee that given a known sequence of - * pseudo-random numbers, we will always pick the same sequence of files and - * folders each time we repeat the test. - */ - public static IResource[] filterResources(IResource[] resources) throws CoreException { - List list = new ArrayList(resources.length); - for (int i = 0; i < resources.length; ++i) { - if (isValidResource(resources[i])) list.add(resources[i]); - } - if (list.size() != resources.length) { - resources = (IResource[]) list.toArray(new IResource[list.size()]); - } - Arrays.sort(resources, new Comparator() { - public int compare(Object a, Object b) { - return ((IResource) a).getName().compareTo(((IResource) b).getName()); - } - }); - return resources; - } - - /*** DIFF SUPPORT ***/ - - public static boolean isEmpty(IDiffContainer node) { - if (node == null) return true; - if (node.getKind() != 0) return false; - IDiffElement[] children = node.getChildren(); - for (int i = 0; i < children.length; i++) { - if (!isEmpty(children[i])) return false; - } - return true; - } - public static boolean isEmpty(IDiffElement element) { - if (element == null) return true; - if (element.getKind() != 0) return false; - if (element instanceof IDiffContainer) { - IDiffElement[] children = ((DiffNode)element).getChildren(); - for (int i = 0; i < children.length; i++) { - if (!isEmpty(children[i])) return false; - } - } - return true; - } - - /*** UI SUPPORT ***/ - - /** - * Opens the specified wizard, then notifies the waiter. - * The WizardDialog instance is passed as argument to notify() in the waiter. - */ - public static void waitForWizardToOpen(Shell parent, IWizard wizard, final Waiter waiter) { - WizardDialog dialog = new WizardDialog(parent, wizard) { - public int open() { - // create the window's controls - create(); - // hook into the event loop so we get called back when the wizard is up and running - final Display display = getContents().getDisplay(); - final WizardDialog dialog = this; - display.asyncExec(new Runnable() { - public void run() { - while (display.readAndDispatch()); // process any other pending messages first - waiter.notify(dialog); - } - }); - // call open (does not create the window's controls a second time) - return super.open(); - } - }; - dialog.open(); - } - - /** - * Notifies the waiter when a Shell matching the specified criteria opens. - * The Shell instance is passed as argument to notify() in the waiter. - * - * @param display the root display - * @param pollingPeriod the number of milliseconds to wait between polls - * @param value a value used for matching - * @param criteria a strategy for matching the controls with a value, - * or null to match any Shell. - * @param waiter the waiter to be notified - */ - public static void waitForShellToOpen(final Display display, final int pollingPeriod, - final Object value, final ICriteria criteria, final Waiter waiter) { - final Runnable hook = new Runnable() { - public void run() { - if (display.isDisposed()) return; - Shell[] shells = display.getShells(); - for (int i = 0; i < shells.length; ++i) { - Shell shell = shells[i]; - if (criteria != null && ! criteria.test(shell, value)) continue; - if (! waiter.notify(shell)) return; - } - // poll again as soon as possible - if (waiter.keepWaiting()) { - display.timerExec(pollingPeriod, this); - } - } - }; - hook.run(); - } - - - /** - * Installs a watchdog for JFace error dialogs for the current display. - * The Dialog instance is passed as argument to notify() in the waiter. - * Recognized dialogs: - * - ErrorDialog - * - InternalErrorDialog - * - * @param display the root display - * @param pollingPeriod the number of milliseconds to wait between polls - * @param waiter the waiter to be notified - */ - public static void waitForErrorDialog(Display display, int pollingPeriod, final Waiter waiter) { - ICriteria criteria = new ICriteria() { - public boolean test(Object candidate, Object value) { - Shell shell = (Shell) candidate; - if (shell.isDisposed()) return false; - Object data = shell.getData(); - if (data == null) return false; - return data instanceof ErrorDialog || data instanceof InternalErrorDialog; - } - }; - waitForShellToOpen(display, pollingPeriod, null, criteria, new Waiter() { - public boolean keepWaiting() { - return waiter.keepWaiting(); - } - - public boolean notify(Object object) { - return waiter.notify(((Shell) object).getData()); - } - }); - } - - /** - * Finds a Control in a Composite hierarchy matching the specified criteria. - * - * @param root the root of the hierarchy to search - * @param clazz the Class representing the precise type of Control to find - * @param value a value used for matching - * @param criteria a strategy for matching the controls with a value, - * or null to match anything of the right class. - * @return the first matching Control, or null if none found. - */ - public static Control findControl(Composite root, Class clazz, Object value, ICriteria criteria) { - if (clazz.isAssignableFrom(root.getClass())) { - if (criteria == null || criteria.test(root, value)) return root; - } - Control[] children = root.getChildren(); - for (int i = 0; i < children.length; ++i) { - final Control candidate = children[i]; - if (candidate instanceof Composite) { - Control c = findControl((Composite) candidate, clazz, value, criteria); - if (c != null) return c; - } else { - if (clazz.isAssignableFrom(candidate.getClass())) { - if (criteria == null || criteria.test(candidate, value)) return candidate; - } - } - } - return null; - } - - /** - * Finds a Control in a Composite hierarchy with the specified text string. - * Note: clazz must specify a Control subclass that defines getText() - * - * @param root the root of the hierarchy to search - * @param clazz the Class representing the precise type of Control to find - * @param text the text string to find - * @return the first matching Control, or null if none found. - */ - public static Control findControlWithText(Composite root, Class clazz, String text) { - return findControl(root, clazz, text, new ICriteria() { - public boolean test(Object control, Object value) { - // getText is only defined on certain subclasses of Composite - // so we must use reflection to find the method - try { - Method m = control.getClass().getMethod("getText", new Class[0]); - String text = (String) m.invoke(control, new Object[0]); - return value.equals(stripMnemonicEscapes(text)); - } catch (Exception e) { - e.printStackTrace(); - Assert.fail("Could not invoke method getText()"); - } - return false; - } - }); - } - - /** - * Posts a fake event to the queue. - * Fills in the event type and widget fields. - * @param event the Event - */ - public static void postEvent(final Widget widget, final int eventType, final Event event) { - Display display = widget.getDisplay(); - event.type = eventType; - event.widget = widget; - display.asyncExec(new Runnable() { - public void run() { - widget.notifyListeners(eventType, event); - } - }); - } - - /** - * Strips mnemonic escapes from a text label. - */ - public static String stripMnemonicEscapes(String label) { - StringBuffer buf = new StringBuffer(); - int length = label.length(); - for (int i = 0; i < length; ++i) { - char c = label.charAt(i); - if (c == '&') { - i += 1; - if (i < length) c = label.charAt(i); - } - buf.append(c); - } - return buf.toString(); - } - - /** - * Process pending events for the current display, until at least the - * specified number of milliseconds elapses. - */ - public static void processEventsUntil(int hiatus) { - Display display = Display.getCurrent(); - Assert.assertNotNull(display); - final boolean done[] = new boolean[] { hiatus == 0 }; - if (hiatus != 0) display.timerExec(hiatus, new Runnable() { - public void run() { done[0] = true; } - }); - for (;;) { - while (display.readAndDispatch()); - if (done[0]) return; - display.sleep(); - } - } - - /** - * Process pending events for the current display, until resumed by the user. - * Very useful for inspecting intermediate results while debugging. - */ - public static void processEventsUntilResumed(String title) { - Display display = Display.getCurrent(); - Assert.assertNotNull(display); - Shell shell = new Shell(display, SWT.CLOSE); - shell.setText("Close me to resume: " + title); - shell.setBounds(0, 0, 500, 30); - shell.open(); - while (! shell.isDisposed()) { - while (! display.readAndDispatch()) display.sleep(); - } - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/Waiter.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/Waiter.java deleted file mode 100644 index 91dd75672..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/Waiter.java +++ /dev/null @@ -1,35 +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.tests.ccvs.ui.old; - - - -/** - * Abstract listener used for the generic problem of waiting for - * something to happen and retrieving some related information. - * e.g. Waiting for a window with a given title to open and getting its handle. - */ -public abstract class Waiter { - /** - * Called when the desired event has occurred. - * @param object an object related to the event, type depends on the context - * @return true to keep waiting, otherwise false - */ - public abstract boolean notify(Object object); - - /** - * Called after each unsuccessful poll for the event. - * @return true to keep waiting, otherwise false - */ - public boolean keepWaiting() { - return true; - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/WorkflowTests.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/WorkflowTests.java deleted file mode 100644 index e5fee208a..000000000 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/old/WorkflowTests.java +++ /dev/null @@ -1,156 +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.tests.ccvs.ui.old; - - -import java.io.File; - -import junit.framework.Test; -import junit.framework.TestSuite; - -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.team.internal.ccvs.core.CVSTag; - -public class WorkflowTests extends CVSUITestCase { - private int FILE_SIZE_MEAN = 16384; - private int FILE_SIZE_VARIANCE = 12288; - private int PROB_BINARY = 5; - public WorkflowTests(Test test) { - super(test); - } - - public static Test suite() { - return new BenchmarkTestSetup(new TestSuite(WorkflowTests.class)); - //return new BenchmarkTestSetup(new WorkflowTests("testTinyWorkflow")); - } - - public void testBigWorkflow() throws Exception { - runWorkflowTests("testBig", BenchmarkTestSetup.BIG_ZIP_FILE); - } - - public void testSmallWorkflow() throws Exception { - runWorkflowTests("testSmall", BenchmarkTestSetup.SMALL_ZIP_FILE); - } - - public void testTinyWorkflow() throws Exception { - runWorkflowTests("testTiny", BenchmarkTestSetup.TINY_ZIP_FILE); - } - - /** - * Runs a series of incoming and outgoing workflow-related tests. - */ - protected void runWorkflowTests(String name, File initialContents) throws Exception { - final SequenceGenerator gen = new SequenceGenerator(); - IProject outProject = createAndImportProject(name, initialContents); - - // test project sharing - startGroup("test project sharing"); - actionShareProject(outProject); - endGroup(); - - // test initial project commit - startGroup("test initial project commit"); - syncCommitResources(new IResource[] { outProject }, null, "initial"); - endGroup(); - - // move the project out of the way - String moduleName = outProject.getName(); - Utils.renameResource(outProject, moduleName + "out"); - outProject = Utils.getProject(moduleName + "out"); - - // test initial project checkout - startGroup("test initial project checkout"); - actionCheckoutProjects(new String[] { moduleName }, new CVSTag[] { new CVSTag() }); - endGroup(); - IProject inProject = Utils.getProject(moduleName); - - // test scenarios - startGroup("test incoming and outgoing change scenarios"); - startGroup("adding a new component - localized additions and some changes"); - Utils.modifyRandomDeepFiles(gen, outProject, 5); - Utils.touchRandomDeepFiles(gen, outProject, 2); - IFolder componentRoot = Utils.createRandomDeepFolder(gen, outProject); - Utils.createRandomDeepFiles(gen, componentRoot, 12, FILE_SIZE_MEAN, FILE_SIZE_VARIANCE, PROB_BINARY); - syncCommitResources(new IResource[] { outProject }, null, ""); - endGroup(); - - startGroup("catching up to a new component - localized additions and some changes"); - syncUpdateResources(new IResource[] { inProject }, null); - endGroup(); - - startGroup("fixing a bug - localized changes"); - Utils.modifyRandomDeepFiles(gen, componentRoot, 2); - Utils.touchRandomDeepFiles(gen, componentRoot, 2); - syncCommitResources(new IResource[] { outProject }, null, ""); - endGroup(); - - startGroup("catching up to a bug fix - localized changes"); - syncUpdateResources(new IResource[] { inProject }, null); - endGroup(); - - startGroup("moving a package - scattered changes, files moved"); - Utils.modifyRandomDeepFiles(gen, outProject, 5); // a few scattered changes - Utils.modifyRandomDeepFiles(gen, componentRoot, 12); // changes to "package" stmt - Utils.renameResource(componentRoot, Utils.makeUniqueName(gen, "folder", null)); - syncCommitResources(new IResource[] { outProject }, null, ""); - endGroup(); - - startGroup("catching up to a moved package - scattered changes, files moved"); - syncUpdateResources(new IResource[] { inProject }, null); - endGroup(); - - startGroup("big refactoring - scattered changes, files renamed and balanced additions/deletions"); - Utils.deleteRandomDeepFiles(gen, outProject, 4); // some stuff deleted - Utils.modifyRandomDeepFiles(gen, outProject, 20); // many scattered changes - Utils.renameRandomDeepFiles(gen, outProject, 5); // renamed some stuff - Utils.createRandomDeepFiles(gen, outProject, 4, FILE_SIZE_MEAN, FILE_SIZE_VARIANCE, PROB_BINARY); // some new stuff added - syncCommitResources(new IResource[] { outProject }, null, ""); - endGroup(); - - startGroup("catching up to a big refactoring - scattered changes, files renamed and balanced additions/deletions"); - syncUpdateResources(new IResource[] { inProject }, null); - endGroup(); - endGroup(); - - // test tagging a project - startGroup("tag project"); - actionCVSTag(new IResource[] { outProject }, "v101"); - endGroup(); - - // replace with remote contents - startGroup("test replace with remote contents scenarios"); - startGroup("no local dirty files, no remote changes"); - actionReplaceWithRemote(new IResource[] { inProject }); - endGroup(); - - startGroup("abandoning some local work, no remote changes"); - Utils.deleteRandomDeepFiles(gen, inProject, 4); // some stuff locally deleted - Utils.modifyRandomDeepFiles(gen, inProject, 6); // a few unimportant changes to forget - Utils.createRandomDeepFiles(gen, inProject, 4, FILE_SIZE_MEAN, FILE_SIZE_VARIANCE, PROB_BINARY); // some new work to abandon - actionReplaceWithRemote(new IResource[] { inProject }); - endGroup(); - - startGroup("no local dirty files, many remote changes"); - // e.g. returning from a long vacation - Utils.deleteRandomDeepFiles(gen, outProject, 10); // some components obsoleted - Utils.modifyRandomDeepFiles(gen, outProject, 42); // many changes - Utils.renameRandomDeepFiles(gen, outProject, 8); // evidence of some refactoring - Utils.createRandomDeepFiles(gen, outProject, 10, FILE_SIZE_MEAN, FILE_SIZE_VARIANCE, PROB_BINARY); // a few new components added - disableLog(); - syncCommitResources(new IResource[] { outProject }, null, ""); - enableLog(); - actionReplaceWithRemote(new IResource[] { inProject }); - endGroup(); - endGroup(); - } -} diff --git a/tests/org.eclipse.team.tests.cvs.core/toc.xml b/tests/org.eclipse.team.tests.cvs.core/toc.xml index c7dbb75e7..83848af71 100644 --- a/tests/org.eclipse.team.tests.cvs.core/toc.xml +++ b/tests/org.eclipse.team.tests.cvs.core/toc.xml @@ -60,5 +60,17 @@ <topic label="General use" href="html/00032.html"> </topic> </topic> + <topic label="Annotate" href="html/00033.html"> + <topic label="Show Annotation Action" href="html/00034.html"> + </topic> + </topic> + <topic label="Label Decorations" href="html/00035.html"> + <topic label="Enablement at startup" href="html/00036.html"> + </topic> + <topic label="Customizations" href="html/00037.html"> + </topic> + <topic label="Decorations in the Synchronize pages" href="html/00038.html"> + </topic> + </topic> </topic> </toc> |