diff options
author | Jean Michel-Lemieux | 2004-02-25 21:33:05 +0000 |
---|---|---|
committer | Jean Michel-Lemieux | 2004-02-25 21:33:05 +0000 |
commit | 17e124117cab197ae83dea9a37fed6d97c12c21a (patch) | |
tree | cf3a04cb2c4d7a5a8c89d78eb5c633bce1f92c2d | |
parent | 1c9e2e0038d84a70ca5c65bdfba279b755dc4ede (diff) | |
download | eclipse.platform.team-17e124117cab197ae83dea9a37fed6d97c12c21a.tar.gz eclipse.platform.team-17e124117cab197ae83dea9a37fed6d97c12c21a.tar.xz eclipse.platform.team-17e124117cab197ae83dea9a37fed6d97c12c21a.zip |
SyncView API released to HEAD.
22 files changed, 0 insertions, 4635 deletions
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/ILocalSyncElement.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/ILocalSyncElement.java deleted file mode 100644 index 29c63a64b..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/ILocalSyncElement.java +++ /dev/null @@ -1,201 +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.core.sync; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.TeamException; - -/** - * <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 <code>ILocalSyncElement</code> describes the relative synchronization of a <b>local</b> - * resource using a <b>base</b> resource for comparison. - * <p> - * Differences between the base and local resources are classified as <b>outgoing changes</b>; - * if there is a difference, the local resource is considered the <b>outgoing resource</b>. </p> - * - * @see IRemoteSyncElement - * - * @since 2.0 - */ -public interface ILocalSyncElement { - - /*==================================================================== - * Constants defining synchronization types: - *====================================================================*/ - - /** - * Sync constant (value 0) indicating element is in sync. - */ - public static final int IN_SYNC = 0; - - /** - * Sync constant (value 1) indicating that one side was added. - */ - public static final int ADDITION = 1; - - /** - * Sync constant (value 2) indicating that one side was deleted. - */ - public static final int DELETION = 2; - - /** - * Sync constant (value 3) indicating that one side was changed. - */ - public static final int CHANGE = 3; - - /** - * Bit mask for extracting the change type. - */ - public static final int CHANGE_MASK = CHANGE; - - /*==================================================================== - * Constants defining synchronization direction: - *====================================================================*/ - - /** - * Sync constant (value 4) indicating a change to the local resource. - */ - public static final int OUTGOING = 4; - - /** - * Sync constant (value 8) indicating a change to the remote resource. - */ - public static final int INCOMING = 8; - - /** - * Sync constant (value 12) indicating a change to both the remote and local resources. - */ - public static final int CONFLICTING = 12; - - /** - * Bit mask for extracting the synchronization direction. - */ - public static final int DIRECTION_MASK = CONFLICTING; - - /*==================================================================== - * Constants defining synchronization conflict types: - *====================================================================*/ - - /** - * Sync constant (value 16) indication that both the local and remote resources have changed - * relative to the base but their contents are the same. - */ - public static final int PSEUDO_CONFLICT = 16; - - /** - * Sync constant (value 32) indicating that both the local and remote resources have changed - * relative to the base but their content changes do not conflict (e.g. source file changes on different - * lines). These conflicts could be merged automatically. - */ - public static final int AUTOMERGE_CONFLICT = 32; - - /** - * Sync constant (value 64) indicating that both the local and remote resources have changed relative - * to the base and their content changes conflict (e.g. local and remote resource have changes on - * same lines). These conflicts can only be correctly resolved by the user. - */ - public static final int MANUAL_CONFLICT = 64; - - /*==================================================================== - * Constants defining synchronization granularity: - *====================================================================*/ - - /** - * Constant (value 1) to only consider timestamp comparisons (e.g. isDirty) when - * calculating the synchronization kind. This is the faster sync compare option but it can result in false - * conflicts. - */ - public static final int GRANULARITY_TIMESTAMP = 1; - - /** - * Constant (value 2) indicating to consider file contents when calculating the synchronization kind. This - * synchronization mode will perform a content comparison only after timestamp operations (isDirty) - * indicate a change. This mode allows conflicts types to be correctly identified. - */ - public static final int GRANULARITY_CONTENTS = 2; - - /** - * Constant (value 4) indicating to consider file contents (potentially ignoring whitespace) - * when calculating the synchronization kind. This synchronization mode will perform a content - * comparison only after timestamp operations (isDirty) indicate a change. - * This mode allows conflicts types to be correctly identified. - */ - public static final int GRANULARITY_CONTENTS_IGNORE_WHITESPACE = 4; - - /** - * Answer a string that describes the simple name of the sync node, which is suitable - * for display to a user. The name will be used in UI operations, so it is expected that - * implementations will cache this value. - * - * @return String the simple name that identifies the resource within its parent container. - */ - public String getName(); - - /** - * Answer if the sync node is a container and may have children. - * - * @return boolean <code>true</code> if the remote resource is a container, and <code> - * false</code> if it is not. - */ - public boolean isContainer(); - - /** - * Answers the local sync element of this node. Returns a non-existing local - * resource handle if the local resource does not exist in the workspace. - * - * @return IResource the local resource handle in this node. There should always be a local - * resource available, however the resource may not exist. - */ - public IResource getLocal(); - - /** - * Answers the base sync element of this node. Returns <code>null</code> - * if there is no base (e.g. conflicting add). - * - * @return IRemoteResource the base resource in this node, or <code>null</code> is there - * is none. - */ - public IRemoteResource getBase(); - - /** - * Answers and array of <code>ILocalSyncElement</code> elements that are immediate - * children of this sync element, in no particular order. The returned sync nodes are - * a combination of the nodes represented by the sync element (e.g. local, base, remote). - * - * @param monitor a progress monitor to indicate the duration of the operation, or - * <code>null</code> if progress reporting is not required. - * - * @return ILocalSyncElement[] array of immediate children of this sync node. - * - * @throws TeamException - */ - public ILocalSyncElement[] members(IProgressMonitor monitor) throws TeamException; - - /** - * Performs a synchronization calculation on the given element based on the local and base - * resources. Returns an integer describing the synchronization state of this element. - * - * @param granularity the granularity at which the elements of this sync element - * should be compared. On of <code>GRANULARITY_TIMESTAMP</code>, or - * <code>GRANULARITY_CONTENTS</code>. - * @param progress a progress monitor to indicate the duration of the operation, or - * <code>null</code> if progress reporting is not required. - * - * @return int an integer describing the synchronization state of this element. - */ - public int getSyncKind(int granularity, IProgressMonitor progress); -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/IRemoteResource.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/IRemoteResource.java deleted file mode 100644 index 5bd09c677..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/IRemoteResource.java +++ /dev/null @@ -1,85 +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.core.sync; - -import java.io.InputStream; - -import org.eclipse.core.resources.IStorage; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.TeamException; - -/** - * <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 resources that are not local. - * - * @since 2.0 - */ -public interface IRemoteResource extends IAdaptable { - - /** - * Answers a string that describes the name of the remote resource. The name may be - * displayed to the user. - * - * @return name of the remote resource. - */ - public String getName(); - - /** - * Answers and array of <code>IRemoteResource</code> elements that are immediate - * children of this remote resource, in no particular order. - * - * @param progress a progress monitor to indicate the duration of the operation, or - * <code>null</code> if progress reporting is not required. - * - * @return array of immediate children of this remote resource. - */ - public IRemoteResource[] members(IProgressMonitor progress) throws TeamException; - - /** - * 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; - - /** - * 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(); - - public String getComment() throws TeamException; - - public String getContentIdentifier() throws TeamException; - - public String getCreatorDisplayName() throws TeamException; - - /** - * Returns an IStorage that contains (or provides access to) the buffered - * contents of the remote resource. Returns <code>null</code> if the remote - * resource does not have contents (i.e. is not a file). - * - * @param monitor - * @return - * @throws TeamException - */ - public IStorage getBufferedStorage(IProgressMonitor monitor) throws TeamException; -} - diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/IRemoteSyncElement.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/IRemoteSyncElement.java deleted file mode 100644 index 03e8ad866..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/IRemoteSyncElement.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.core.sync; - - -/** - * <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 <code>IRemoteSyncElement</code> describes the relative synchronization of a <b>local</b> - * and <b>remote</b> resource using a <b>base</b> resource for comparison. - * <p> - * Differences between the base and remote resources are classified as <b>incoming changes</b>; - * if there is a difference, the remote resource is considered the <b>incoming resource</b>. </p> - * - * @see ILocalSyncElement - * - * @since 2.0 - */ -public interface IRemoteSyncElement extends ILocalSyncElement { - - /** - * Answer the remote sync element of this node. Returns <code>null</code> - * if there is no remote. - * - * @return the remote resource in this sync element, or <code>null</code> is there - * is none. - */ - public IRemoteResource getRemote(); - - /** - * Answers <code>true</code> if the base tree is not to be considered during sync - * comparisons and <code>false</code> if it should. If the base tree is ignored the - * sync comparison can be based on isOutOfDate and isDirty methods only. - */ - public boolean isThreeWay(); -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/LocalSyncElement.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/LocalSyncElement.java deleted file mode 100644 index 8a76bc721..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/LocalSyncElement.java +++ /dev/null @@ -1,123 +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.core.sync; - -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.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.TeamException; - -/** - * <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 standard abstract class that provides implementations for <code>ILocalSyncElement</code> - * methods. - * - * @since 2.0 - */ -public abstract class LocalSyncElement implements ILocalSyncElement { - - /** - * Creates a client specific sync element from a <b>local</b> and <b>base</b> - * resources. The <b>base</b> resource may be <code>null</code> and should be - * intialized by the client if available. - * - * @param local the local resource in the workbench. Will never be <code>null</code>. - * @param base the base resource, may me <code>null</code>. - * @param data client specific data. - * - * @return a client specific sync element. - */ - public abstract ILocalSyncElement create(IResource local, IRemoteResource base, Object data); - - /** - * Client data that is passed to every <code>create()</code> call. - * - * @return client specific data that will be passed to create. - */ - protected abstract Object getData(); - - /** - * Client can decide is a specific element should be ignored from this sync element's - * children. - * - * @param resource the resource to be queried. - * - * @return <code>true</code> if this element should be ignored and not considered an - * immediate child of this element, and <code>false</code> otherwise. - */ - protected abstract boolean isIgnored(IResource resource); - - /* - * @see ILocalSyncElement#getSyncKind(int, IProgressMonitor) - */ - public int getSyncKind(int granularity, IProgressMonitor progress) { - - // XXX not sure how local sync will be used? - int sync = IN_SYNC; - return sync; - } - - /* - * @see ILocalSyncElement#getName() - */ - public String getName() { - return getLocal().getName(); - } - - /* - * @see ILocalSyncElement#isContainer() - */ - public boolean isContainer() { - return getLocal().getType() != IResource.FILE; - } - - /* - * @see ILocalSyncElement#members(IProgressMonitor) - */ - public ILocalSyncElement[] members(IProgressMonitor monitor) throws TeamException { - try { - if(getLocal().getType() != IResource.FILE) { - IResource[] members = ((IContainer)getLocal()).members(); - List syncElements = new ArrayList(5); - for (int i = 0; i < members.length; i++) { - IResource iResource = members[i]; - // the base is initialy set to null, however the concrete subclass should - // initialize the base if one is available. - if(!isIgnored(iResource)) { - syncElements.add(create(iResource, null, getData())); - } - } - return (ILocalSyncElement[]) syncElements.toArray(new ILocalSyncElement[syncElements.size()]); - } else { - return new ILocalSyncElement[0]; - } - } catch(CoreException e) { - throw new TeamException(e.getStatus()); - } - } - - public boolean equals(Object other) { - if(other == this) return true; - if(other instanceof ILocalSyncElement) { - return getLocal().equals(((ILocalSyncElement)other).getLocal()); - } - return false; - } -}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/RemoteContentsCache.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/RemoteContentsCache.java deleted file mode 100644 index 210ca912b..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/RemoteContentsCache.java +++ /dev/null @@ -1,256 +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.core.sync; - -import java.io.File; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.jobs.ILock; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.core.Policy; -import org.eclipse.team.internal.core.TeamPlugin; - -/** - * This class implements a caching facility that can be used by TeamProviders to cache contents - */ -public class RemoteContentsCache { - - // Directory to cache file contents - private static final String CACHE_DIRECTORY = ".cache"; //$NON-NLS-1$ - // Maximum lifespan of local cache file, in milliseconds - private static final long CACHE_FILE_LIFESPAN = 60*60*1000; // 1hr - - // Map of registered cahces indexed by local name of a QualifiedName - private static Map caches = new HashMap(); // String (local name) > RemoteContentsCache - - private String name; - private Map cacheEntries; - private long lastCacheCleanup; - private int cacheDirSize; - - // Lock used to serialize the writting of cache contents - private ILock lock = Platform.getJobManager().newLock(); - - /** - * Enables the use of remote contents caching for the given cacheId. The cache ID must be unique. - * A good candidate for this ID is the plugin ID of the plugin peforming the caching. - * - * @param cacheId the unique Id of the cache being enabled - * @throws TeamException if the cache area on disk could not be properly initialized - */ - public static synchronized void enableCaching(String cacheId) { - if (isCachingEnabled(cacheId)) return; - RemoteContentsCache cache = new RemoteContentsCache(cacheId); - try { - cache.createCacheDirectory(); - } catch (TeamException e) { - // Log the exception and continue - TeamPlugin.log(e); - } - caches.put(cacheId, cache); - } - - /** - * Returns whether caching has been enabled for the given Id. A cache should only be enabled once. - * It is conceivable that a cache be persisted over workbench invocations thus leading to a cahce that - * is enabled on startup without intervention by the owning plugin. - * - * @param cacheId the unique Id of the cache - * @return true if caching for the given Id is enabled - */ - public static boolean isCachingEnabled(String cacheId) { - return getCache(cacheId) != null; - } - - /** - * Disable the cache, dispoing of any file contents in the cache. - * - * @param cacheId the unique Id of the cache - * @throws TeamException if the cached contents could not be deleted from disk - */ - public static void disableCache(String cacheId) { - RemoteContentsCache cache = getCache(cacheId); - if (cache == null) { - // There is no cache to dispose of - return; - } - caches.remove(cacheId); - try { - cache.deleteCacheDirectory(); - } catch (TeamException e) { - // Log the exception and continue - TeamPlugin.log(e); - } - } - - /** - * Return the cache for the given id or null if caching is not enabled for the given id. - * @param cacheId - * @return - */ - public static synchronized RemoteContentsCache getCache(String cacheId) { - return (RemoteContentsCache)caches.get(cacheId); - } - - private RemoteContentsCache(String name) { - this.name = name; - } - - /** - * Return whether the cache contains an entry for the given id. Register a hit if it does. - * @param id the id of the cache entry - * @return true if there are contents cached for the id - */ - public boolean hasEntry(String id) { - return internalGetCacheEntry(id) != null; - } - - protected IPath getCachePath() { - return getStateLocation().append(CACHE_DIRECTORY).append(name); - } - - private IPath getStateLocation() { - return TeamPlugin.getPlugin().getStateLocation(); - } - - private void clearOldCacheEntries() { - long current = new Date().getTime(); - if ((lastCacheCleanup!=-1) && (current - lastCacheCleanup < CACHE_FILE_LIFESPAN)) return; - List stale = new ArrayList(); - for (Iterator iter = cacheEntries.values().iterator(); iter.hasNext();) { - RemoteContentsCacheEntry entry = (RemoteContentsCacheEntry) iter.next(); - long lastHit = entry.getLastAccessTimeStamp(); - if ((current - lastHit) > CACHE_FILE_LIFESPAN){ - stale.add(entry); - } - } - for (Iterator iter = stale.iterator(); iter.hasNext();) { - RemoteContentsCacheEntry entry = (RemoteContentsCacheEntry) iter.next(); - entry.dispose(); - } - } - - private void purgeFromCache(String id) { - RemoteContentsCacheEntry entry = (RemoteContentsCacheEntry)cacheEntries.get(id); - File f = entry.getFile(); - try { - deleteFile(f); - } catch (TeamException e) { - // Ignore the deletion failure. - // A failure only really matters when purging the directory on startup - } - cacheEntries.remove(id); - } - - private void createCacheDirectory() throws TeamException { - IPath cacheLocation = getCachePath(); - File file = cacheLocation.toFile(); - if (file.exists()) { - deleteFile(file); - } - if (! file.mkdirs()) { - throw new TeamException(Policy.bind("RemoteContentsCache.fileError", file.getAbsolutePath())); //$NON-NLS-1$ - } - cacheEntries = new HashMap(); - lastCacheCleanup = -1; - cacheDirSize = 0; - } - - private void deleteCacheDirectory() throws TeamException { - cacheEntries = null; - lastCacheCleanup = -1; - cacheDirSize = 0; - IPath cacheLocation = getCachePath(); - File file = cacheLocation.toFile(); - if (file.exists()) { - try { - deleteFile(file); - } catch (TeamException e) { - // Don't worry about problems deleting. - // The only case that matters is when the cache directory is created - } - } - } - - private void deleteFile(File file) throws TeamException { - if (file.isDirectory()) { - File[] children = file.listFiles(); - for (int i = 0; i < children.length; i++) { - deleteFile(children[i]); - } - } - if (! file.delete()) { - throw new TeamException(Policy.bind("RemoteContentsCache.fileError", file.getAbsolutePath())); //$NON-NLS-1$ - } - } - - /** - * Purge the given cache entry from the cache. This method should only be invoked from - * an instance of RemoteContentsCacheEntry after it has set it's state to DISPOSED. - * @param entry - */ - protected void purgeFromCache(RemoteContentsCacheEntry entry) { - purgeFromCache(entry.getId()); - } - - private RemoteContentsCacheEntry internalGetCacheEntry(String id) { - RemoteContentsCacheEntry entry = (RemoteContentsCacheEntry)cacheEntries.get(id); - if (entry != null) { - entry.registerHit(); - } - return entry; - } - - /** - * @param id the id that uniquely identifes the remote resource that is cached. - * @return - */ - public synchronized RemoteContentsCacheEntry getCacheEntry(String id) { - if (cacheEntries == null) { - // This probably means that the cache has been disposed - throw new IllegalStateException(Policy.bind("RemoteContentsCache.cacheDisposed", name)); //$NON-NLS-1$ - } - RemoteContentsCacheEntry entry = internalGetCacheEntry(id); - if (entry == null) { - // cache miss - entry = createCacheEntry(id); - } - return entry; - } - - private RemoteContentsCacheEntry createCacheEntry(String id) { - clearOldCacheEntries(); - String filePath = String.valueOf(cacheDirSize++); - RemoteContentsCacheEntry entry = new RemoteContentsCacheEntry(this, id, filePath); - cacheEntries.put(id, entry); - return entry; - } - - public String getName() { - return name; - } - - /** - * Provide access to the lock for the cache. This method should only be used by a cache entry. - * @return Returns the lock. - */ - protected ILock getLock() { - return lock; - } - -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/RemoteContentsCacheEntry.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/RemoteContentsCacheEntry.java deleted file mode 100644 index 3e66789d3..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/RemoteContentsCacheEntry.java +++ /dev/null @@ -1,238 +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.core.sync; - -import java.io.BufferedOutputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Date; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.core.Policy; - -/** - * This class provides the implementation for the ICacheEntry - */ -public class RemoteContentsCacheEntry { - - public static final int UNINITIALIZED = 0; - public static final int READY = 1; - public static final int DISPOSED = 2; - - private String id; - private String filePath; - private RemoteContentsCache cache; - private byte[] syncBytes; - private int state = UNINITIALIZED; - private long lastAccess; - - public RemoteContentsCacheEntry(RemoteContentsCache cache, String id, String filePath) { - state = UNINITIALIZED; - this.cache = cache; - this.id = id; - this.filePath = filePath; - registerHit(); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.ICacheEntry#getContents() - */ - public InputStream getContents() throws TeamException { - if (state != READY) return null; - registerHit(); - File ioFile = getFile(); - try { - try { - if (ioFile.exists()) { - return new FileInputStream(ioFile); - } - } catch (IOException e) { - // Try to purge the cache and continue - cache.purgeFromCache(this); - throw e; - } - } catch (IOException e) { - // We will end up here if we couldn't read or delete the cache file - throw new TeamException(Policy.bind("RemoteContentsCache.fileError", ioFile.getAbsolutePath()), e); //$NON-NLS-1$ - } - // This can occur when there is no remote contents - return new ByteArrayInputStream(new byte[0]); - } - - protected File getFile() { - return new File(cache.getCachePath().toFile(), filePath); - } - - /** - * Set the contents of for this cache entry. This method supports concurrency by only allowing - * one cache entry to be written at a time. In the case of two concurrent writes to the same cache entry, - * the contents from the first write is used and the content from subsequent writes is ignored. - * @param stream an InputStream that provides the contents to be cached - * @param monitor a progress monitor - * @throws TeamException if the entry is DISPOSED or an I/O error occurres - */ - public void setContents(InputStream stream, IProgressMonitor monitor) throws TeamException { - // Use a lock to only allow one write at a time - try { - beginOperation(); - internalSetContents(stream, monitor); - } finally { - endOperation(); - } - } - - private void endOperation() { - cache.getLock().release(); - } - - private void beginOperation() { - cache.getLock().acquire(); - } - - private void internalSetContents(InputStream stream, IProgressMonitor monitor) throws TeamException { - // if the state is DISPOSED then there is a problem - if (state == DISPOSED) { - throw new TeamException("Cache entry in {0} for {1} has been disposed" + cache.getName() + id); - } - // Otherwise, the state is UNINITIALIZED or READY so we can proceed - registerHit(); - File ioFile = getFile(); - try { - - // Open the cache file for writing - OutputStream out; - try { - if (state == UNINITIALIZED) { - out = new BufferedOutputStream(new FileOutputStream(ioFile)); - } else { - // If the entry is READY, the contents must have been read in another thread. - // We still need to red the contents but they can be ignored since presumably they are the same - out = new ByteArrayOutputStream(); - } - } catch (FileNotFoundException e) { - throw new TeamException(Policy.bind("RemoteContentsCache.fileError", ioFile.getAbsolutePath()), e); //$NON-NLS-1$ - } - - // Transfer the contents - try { - try { - byte[] buffer = new byte[1024]; - int read; - while ((read = stream.read(buffer)) >= 0) { - Policy.checkCanceled(monitor); - out.write(buffer, 0, read); - } - } finally { - out.close(); - } - } catch (IOException e) { - // Make sure we don't leave the cache file around as it may not have the right contents - cache.purgeFromCache(this); - throw e; - } - - // Mark the cache entry as ready - state = READY; - } catch (IOException e) { - throw new TeamException(Policy.bind("RemoteContentsCache.fileError", ioFile.getAbsolutePath()), e); //$NON-NLS-1$ - } finally { - try { - stream.close(); - } catch (IOException e1) { - // Ignore close errors - } - } - - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.ICacheEntry#getSyncBytes(byte[]) - */ - public byte[] getSyncBytes() { - return syncBytes; - } - - /** - * Set the sync bytes associated with the cached remote contents. - * This method is sychronized to ensure atomic setting of the bytes. - * @param bytes - */ - public void setSyncBytes(byte[] bytes) { - try { - beginOperation(); - syncBytes = bytes; - } finally { - endOperation(); - } - syncBytes = bytes; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.ICacheEntry#getState() - */ - public int getState() { - return state; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.ICacheEntry#getSize() - */ - public long getSize() { - if (state != READY) return 0; - File ioFile = getFile(); - if (ioFile.exists()) { - return ioFile.length(); - } - return 0; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.ICacheEntry#getLastAccessTimeStamp() - */ - public long getLastAccessTimeStamp() { - return lastAccess; - } - - /** - * Registers a hit on this cache entry. This updates the last access timestamp. - * Thsi method is intended to only be invokded from inside this class or the cahce itself. - * Other clients should not use it. - */ - protected void registerHit() { - lastAccess = new Date().getTime(); - } - - public void dispose() { - // Use a lock to avoid changing state while another thread may be writting - try { - beginOperation(); - state = DISPOSED; - cache.purgeFromCache(this); - } finally { - endOperation(); - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.ICacheEntry#getId() - */ - public String getId() { - return id; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/RemoteSyncElement.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/RemoteSyncElement.java deleted file mode 100644 index 420740d2e..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/sync/RemoteSyncElement.java +++ /dev/null @@ -1,441 +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.core.sync; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -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.IStorage; -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.team.core.TeamException; -import org.eclipse.team.internal.core.Assert; -import org.eclipse.team.internal.core.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. - * - * A standard abstract class that provides implementations for interesting - * <code>IRemoteSyncElement</code> methods. The <code>members</code> method - * provided will create a unified tree based on the local, base, and remote - * children. The <code>getSyncKind</code> method will calculate the relative - * sync kind of the remote node. - * - * @since 2.0 - */ -public abstract class RemoteSyncElement extends LocalSyncElement implements IRemoteSyncElement { - - /** - * Creates a client specific sync element from a <b>local</b>, <b>base</b>, and - * <b>remote</b> resources. The <b>base</b> and <b>remote</b> resource may be - * <code>null</code>. - * - * @param local the local resource in the workbench. Will never be <code>null</code>. - * @param base the base resource, may me <code>null</code>. - * @param remote the remote resource, may be <code>null</code>. - * @param data client specific data. - * - * @return a client specific sync element. - */ - public abstract IRemoteSyncElement create(boolean isThreeWay, IResource local, IRemoteResource base, IRemoteResource remote, Object data); - - /* - * @see ILocalSyncElement#members() - */ - public ILocalSyncElement[] members(IProgressMonitor progress) throws TeamException { - // create union of the local, base, and remote trees - IRemoteResource remote = getRemote(); - IRemoteResource base = getBase(); - IResource local = getLocal(); - - IRemoteResource[] remoteChildren = - remote != null ? remote.members(progress) : new IRemoteResource[0]; - - IRemoteResource[] baseChildren = - base != null ? base.members(progress) : new IRemoteResource[0]; - - IResource[] localChildren; - try { - if( local.getType() != IResource.FILE && local.exists() ) { - localChildren = ((IContainer)local).members(); - } else { - localChildren = new IResource[0]; - } - } catch(CoreException e) { - throw new TeamException(e.getStatus()); - } - - if (remoteChildren.length > 0 || localChildren.length > 0) { - List syncChildren = new ArrayList(10); - Set allSet = new HashSet(20); - Map localSet = null; - Map remoteSet = null; - Map baseSet = 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); - } - } - - if (baseChildren.length > 0) { - baseSet = new HashMap(10); - for (int i = 0; i < baseChildren.length; i++) { - IRemoteResource baseChild = baseChildren[i]; - String name = baseChild.getName(); - baseSet.put(name, baseChild); - 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; - - IRemoteResource baseChild = - baseSet != null ? (IRemoteResource) baseSet.get(keyChildName) : null; - - - if (localChild == null) { - // there has to be a remote resource available if we got this far - Assert.isTrue(remoteChild != null || baseChild != null); - boolean isContainer = remoteChild != null ? remoteChild.isContainer() : baseChild.isContainer(); - - localChild = getResourceChild(local /* parent */, keyChildName, isContainer); - } - - if(!localChild.exists() || !isIgnored(localChild)) { - syncChildren.add(create(isThreeWay(), localChild, baseChild, remoteChild, getData())); - } - } - return (IRemoteSyncElement[]) syncChildren.toArray(new IRemoteSyncElement[syncChildren.size()]); - } - else { - return new IRemoteSyncElement[0]; - } - } - - /* - * @see ILocalSyncElement#getSyncKind(int, IProgressMonitor) - */ - public int getSyncKind(int granularity, IProgressMonitor progress) { - progress = Policy.monitorFor(progress); - int description = IN_SYNC; - - IResource local = getLocal(); - IRemoteResource remote = getRemote(); - IRemoteResource base = getBase(); - - boolean localExists = getLocal().exists(); - - if (isThreeWay()) { - if (base == null) { - if (remote == null) { - if (!localExists) { - Assert.isTrue(false); - } else { - description = OUTGOING | ADDITION; - } - } else { - if (!localExists) { - description = INCOMING | ADDITION; - } else { - description = CONFLICTING | ADDITION; - try { - progress.beginTask(null, 60); - if (isGranularityContents(granularity) && - compare(granularity, true, local, remote, Policy.subMonitorFor(progress, 30))) { - description |= PSEUDO_CONFLICT; - } - } finally { - progress.done(); - } - } - } - } else { - if (!localExists) { - if (remote == null) { - description = CONFLICTING | DELETION | PSEUDO_CONFLICT; - } else { - if (compare(granularity, false, base, remote, progress)) - description = OUTGOING | DELETION; - else - description = CONFLICTING | CHANGE; - } - } else { - if (remote == null) { - if (compare(granularity, false, local, base, progress)) - description = INCOMING | DELETION; - else - description = CONFLICTING | CHANGE; - } else { - progress.beginTask(null, 90); - boolean ay = compare(granularity, false, local, base, Policy.subMonitorFor(progress, 30)); - boolean am = compare(granularity, false, base, remote, Policy.subMonitorFor(progress, 30)); - if (ay && am) { - // in-sync - } else if (ay && !am) { - description = INCOMING | CHANGE; - } else if (!ay && am) { - description = OUTGOING | CHANGE; - } else { - description = CONFLICTING | CHANGE; - if (isGranularityContents(granularity) && - compare(granularity, true, local, remote, Policy.subMonitorFor(progress, 30))) { - description |= PSEUDO_CONFLICT; - } - } - progress.done(); - } - } - } - } else { // two compare without access to base contents - if (remote == null) { - if (!localExists) { - Assert.isTrue(false); - // shouldn't happen - } else { - description= DELETION; - } - } else { - if (!localExists) { - description= ADDITION; - } else { - if (! compare(granularity, false, local, remote, Policy.subMonitorFor(progress, 30))) - description= CHANGE; - } - } - } - return description; - } - - /** - * Helper methods for comparisons that returns true if the resource contents are the same. - * - * If timestampDiff is true then the timestamps don't differ and there's no point checking the - * contents. - */ - protected boolean compare(int granularity, boolean force, IResource e1, IRemoteResource e2, IProgressMonitor monitor) { - boolean timestampEquals; - if (force) { - timestampEquals = false; - } else { - timestampEquals = timestampEquals(e1, e2); - } - if (!timestampEquals && isGranularityContents(granularity)) { - try { - monitor.beginTask(null, 100); - return contentsEqual( - getContents(e1, Policy.subMonitorFor(monitor, 50)), - getContents(e2, Policy.subMonitorFor(monitor, 50)), - granularity == GRANULARITY_CONTENTS_IGNORE_WHITESPACE); - } finally { - monitor.done(); - } - } else { - return timestampEquals; - } - } - - protected boolean compare(int granularity, boolean force, IRemoteResource e1, IRemoteResource e2, IProgressMonitor monitor) { - boolean timestampEquals; - if (force) { - timestampEquals = false; - } else { - timestampEquals = timestampEquals(e1, e2); - } - if (!timestampEquals && isGranularityContents(granularity)) { - try { - monitor.beginTask(null, 100); - return contentsEqual( - getContents(e1, Policy.subMonitorFor(monitor, 50)), - getContents(e2, Policy.subMonitorFor(monitor, 50)), - granularity == GRANULARITY_CONTENTS_IGNORE_WHITESPACE); - } finally { - monitor.done(); - } - } else { - return timestampEquals; - } - } - - protected abstract boolean timestampEquals(IResource e1, IRemoteResource e2); - protected abstract boolean timestampEquals(IRemoteResource e1, IRemoteResource e2); - - protected boolean isGranularityContents(int granularity) { - return granularity != GRANULARITY_TIMESTAMP; - } - - private InputStream getContents(IResource resource, IProgressMonitor monitor) { - try { - if (resource instanceof IStorage) - return new BufferedInputStream(((IStorage) resource).getContents()); - return null; - } catch (CoreException e) { - return null; - } - } - - private InputStream getContents(IRemoteResource remote, IProgressMonitor monitor) { - try { - if (!remote.isContainer()) - return new BufferedInputStream(remote.getContents(monitor)); - return null; - } catch (TeamException exception) { - // The remote node has gone away . - return null; - } - } - - /** - * Returns <code>true</code> if both input streams byte contents is identical. - * - * @param input1 first input to contents compare - * @param input2 second input to contents compare - * @return <code>true</code> if content is equal - */ - private boolean contentsEqual(InputStream is1, InputStream is2, boolean ignoreWhitespace) { - if (is1 == is2) - return true; - - if (is1 == null && is2 == null) // no byte contents - return true; - - try { - if (is1 == null || is2 == null) // only one has contents - return false; - - while (true) { - int c1 = is1.read(); - while (ignoreWhitespace && isWhitespace(c1)) c1 = is1.read(); - int c2 = is2.read(); - while (ignoreWhitespace && isWhitespace(c2)) c2 = is2.read(); - if (c1 == -1 && c2 == -1) - return true; - if (c1 != c2) - break; - - } - } catch (IOException ex) { - } finally { - if (is1 != null) { - try { - is1.close(); - } catch (IOException ex) { - } - } - if (is2 != null) { - try { - is2.close(); - } catch (IOException ex) { - } - } - } - return false; - } - - /* - * Skip all whitspace. - */ - private boolean isWhitespace(int c) { - if (c == -1) return false; - return Character.isWhitespace((char)c); - } - - /* - * 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)); - } - } - - /* - * @see Object#toString() - */ - public String toString() { - return getName() + kindToString(getSyncKind(GRANULARITY_TIMESTAMP, null)); - } - - static public String kindToString(int kind) { - String label = ""; //$NON-NLS-1$ - if(kind==IN_SYNC) { - label = Policy.bind("RemoteSyncElement.insync"); //$NON-NLS-1$ - } else { - switch(kind & DIRECTION_MASK) { - case CONFLICTING: label = Policy.bind("RemoteSyncElement.conflicting"); break; //$NON-NLS-1$ - case OUTGOING: label = Policy.bind("RemoteSyncElement.outgoing"); break; //$NON-NLS-1$ - case INCOMING: label = Policy.bind("RemoteSyncElement.incoming"); break; //$NON-NLS-1$ - } - switch(kind & CHANGE_MASK) { - case CHANGE: label = Policy.bind("concatStrings", label, Policy.bind("RemoteSyncElement.change")); break; //$NON-NLS-1$ //$NON-NLS-2$ - case ADDITION: label = Policy.bind("concatStrings", label, Policy.bind("RemoteSyncElement.addition")); break; //$NON-NLS-1$ //$NON-NLS-2$ - case DELETION: label = Policy.bind("concatStrings", label, Policy.bind("RemoteSyncElement.deletion")); break; //$NON-NLS-1$ //$NON-NLS-2$ - } - if((kind & MANUAL_CONFLICT) != 0) { - label = Policy.bind("concatStrings", label, Policy.bind("RemoteSyncElement.manual")); //$NON-NLS-1$ //$NON-NLS-2$ - } - if((kind & AUTOMERGE_CONFLICT) != 0) { - label = Policy.bind("concatStrings", label, Policy.bind("RemoteSyncElement.auto")); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - return Policy.bind("RemoteSyncElement.delimit", label); //$NON-NLS-1$ - } -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/merge/MergeEditorInput.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/merge/MergeEditorInput.java deleted file mode 100644 index 0e0e73135..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/merge/MergeEditorInput.java +++ /dev/null @@ -1,97 +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.merge; - - -import org.eclipse.compare.structuremergeviewer.ICompareInput; -import org.eclipse.compare.structuremergeviewer.IDiffContainer; -import org.eclipse.compare.structuremergeviewer.IDiffElement; -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.resources.RemoteFile; -import org.eclipse.team.internal.ccvs.ui.Policy; -import org.eclipse.team.internal.ccvs.ui.sync.CVSSyncCompareInput; -import org.eclipse.team.internal.ui.sync.MergeResource; -import org.eclipse.team.internal.ui.sync.SyncView; -import org.eclipse.team.internal.ui.sync.TeamFile; - -public class MergeEditorInput extends CVSSyncCompareInput { - CVSTag start; - CVSTag end; - - public MergeEditorInput(IResource[] resources, CVSTag start, CVSTag end) { - // we have to perform content comparison since files in different branches - // may have different revisions but the same contents. Consider these files - // for merge purposes as equal. - super(resources, IRemoteSyncElement.GRANULARITY_CONTENTS); - this.start = start; - this.end = end; - } - public Viewer createDiffViewer(Composite parent) { - Viewer viewer = super.createDiffViewer(parent); - getViewer().syncModeChanged(SyncView.SYNC_MERGE); - 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]; - IRemoteResource base = CVSWorkspaceRoot.getRemoteTree(resource, start, Policy.subMonitorFor(monitor, 50)); - IRemoteResource remote = CVSWorkspaceRoot.getRemoteTree(resource, end, Policy.subMonitorFor(monitor, 50)); - trees[i] = new CVSRemoteSyncElement(true /*three way*/, resource, base, remote); - } - } finally { - monitor.done(); - } - return trees; - } - public CVSTag getStartTag() { - return start; - } - public CVSTag getEndTag() { - return end; - } - public String getTitle() { - return Policy.bind("MergeEditorInput.title", start.getName(), end.getName()); //$NON-NLS-1$ - } - protected void contentsChanged(ICompareInput source) { - } - - /* - * Override collectResourceChanges to only determine the true sync state for incomming changes - */ - protected IDiffElement collectResourceChanges(IDiffContainer parent, IRemoteSyncElement tree, IProgressMonitor pm) throws TeamException { - if ( ! tree.isContainer()) { - CVSRemoteSyncElement cvsTree = (CVSRemoteSyncElement)tree; - RemoteFile base = (RemoteFile)cvsTree.getBase(); - RemoteFile remote = (RemoteFile)cvsTree.getRemote(); - if (base != null && remote != null && base.getRevision().equals(remote.getRevision())) { - // If the base and remote are the same, we don't have an incomming change - MergeResource mergeResource = new MergeResource(tree); - TeamFile file = new TeamFile(parent, mergeResource, IRemoteSyncElement.IN_SYNC, getShell()); - return file; - } - } - return super.collectResourceChanges(parent, tree, pm); - } -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/merge/OverrideUpdateMergeAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/merge/OverrideUpdateMergeAction.java deleted file mode 100644 index 80c87f613..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/merge/OverrideUpdateMergeAction.java +++ /dev/null @@ -1,67 +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.merge; - - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.ccvs.core.resources.CVSRemoteSyncElement; -import org.eclipse.team.internal.ccvs.ui.IHelpContextIds; -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.CVSSyncCompareInput; -import org.eclipse.team.internal.ui.sync.ITeamNode; -import org.eclipse.team.internal.ui.sync.SyncSet; - -public class OverrideUpdateMergeAction extends UpdateMergeAction { - public OverrideUpdateMergeAction(CVSSyncCompareInput model, ISelectionProvider sp, String label, Shell shell) { - super(model, sp, label, shell); - } - /* - * Override removeNonApplicableNodes because conflicting nodes should not be removed from this set. - */ - protected void removeNonApplicableNodes(SyncSet set, int syncMode) { - set.removeOutgoingNodes(); - set.removeIncomingNodes(); - } - protected boolean isEnabled(ITeamNode node) { - // The force update action is enabled only for conflicting and outgoing changes - SyncSet set = new SyncSet(new StructuredSelection(node)); - return (set.hasConflicts() && hasRealChanges(node, new int[] { ITeamNode.CONFLICTING })); - } - /** - * @see MergeAction#getHelpContextID() - */ - protected String getHelpContextID() { - return IHelpContextIds.MERGE_FORCED_UPDATE_ACTION; - } - - /** - * This method is the same as the inherited methd but it does not unmanage - * because merging should leave the files as outgoing deletions - * - * @see org.eclipse.team.internal.ccvs.ui.sync.UpdateSyncAction#runLocalDeletions(ITeamNode[], RepositoryManager, IProgressMonitor) - */ - protected void runLocalDeletions(ITeamNode[] nodes, RepositoryManager manager, IProgressMonitor monitor) throws TeamException, CoreException { - monitor.beginTask(null, nodes.length * 100); - for (int i = 0; i < nodes.length; i++) { - ITeamNode node = nodes[i]; - CVSRemoteSyncElement element = CVSSyncCompareInput.getSyncElementFrom(node); - deleteAndKeepHistory(element.getLocal(), Policy.subMonitorFor(monitor, 100)); - } - monitor.done(); - } - -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/merge/UpdateMergeAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/merge/UpdateMergeAction.java deleted file mode 100644 index 80239455c..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/merge/UpdateMergeAction.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.ccvs.ui.merge; - - -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.IProgressMonitor; -import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.jface.viewers.ISelectionProvider; -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.client.Command; -import org.eclipse.team.internal.ccvs.core.client.Update; -import org.eclipse.team.internal.ccvs.core.resources.CVSRemoteSyncElement; -import org.eclipse.team.internal.ccvs.ui.IHelpContextIds; -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.CVSSyncCompareInput; -import org.eclipse.team.internal.ccvs.ui.sync.UpdateSyncAction; -import org.eclipse.team.internal.ui.sync.ITeamNode; - -/* - * To be done: - * 1. add another action that allows a force merge merging since we can't tell the manual vs automatic conflicts when building the sync tree. - * 2. fix progress monitoring - */ -public class UpdateMergeAction extends UpdateSyncAction { - public UpdateMergeAction(CVSSyncCompareInput model, ISelectionProvider sp, String label, Shell shell) { - super(model, sp, label, shell); - } - - protected void runUpdateDeletions(ITeamNode[] nodes, RepositoryManager manager, IProgressMonitor monitor) throws TeamException { - runUpdateDeep(nodes, manager, monitor); - } - - /* - * @see UpdateSyncAction#runUpdateDeep(IProgressMonitor, List, RepositoryManager) - * incoming-change - * incoming-deletion - */ - protected void runUpdateDeep(ITeamNode[] nodes, RepositoryManager manager, IProgressMonitor monitor) throws TeamException { - ITeamNode[] incoming = removeOutgoing(nodes); - monitor.beginTask(null, 1000 * incoming.length); - try { - for (int i = 0; i < incoming.length; i++) { - CVSRemoteSyncElement element = CVSSyncCompareInput.getSyncElementFrom(incoming[i]); - if(element!=null) { - makeRemoteLocal(element, new SubProgressMonitor(monitor, 1000)); - } - } - } finally { - monitor.done(); - } - } - - /* - * @see UpdateSyncAction#runUpdateIgnoreLocalShallow(IProgressMonitor, List, RepositoryManager) - * incoming-addition - * incoming-conflict (no-merge) - */ - protected void runUpdateIgnoreLocalShallow(ITeamNode[] nodes, RepositoryManager manager, IProgressMonitor monitor) throws TeamException { - runUpdateDeep(nodes, manager, monitor); - } - - /* - * @see UpdateSyncAction#runUpdateShallow(ITeamNode[], RepositoryManager, IProgressMonitor) - * incoming-conflict (auto-mergeable) - */ - protected void runUpdateShallow(ITeamNode[] nodes, RepositoryManager manager, IProgressMonitor monitor) throws TeamException { - mergeWithLocal(nodes, manager, false, monitor); - } - - protected void mergeWithLocal(ITeamNode[] nodes, RepositoryManager manager, boolean createBackup, IProgressMonitor monitor) throws TeamException { - CVSTag startTag = ((MergeEditorInput)getDiffModel()).getStartTag(); - CVSTag endTag = ((MergeEditorInput)getDiffModel()).getEndTag(); - - Command.LocalOption[] options = new Command.LocalOption[] { - Command.DO_NOT_RECURSE, - Update.makeArgumentOption(Update.JOIN, startTag.getName()), - Update.makeArgumentOption(Update.JOIN, endTag.getName()) }; - - // run a join update using the start and end tags and the join points - manager.update(getIResourcesFrom(nodes), options, createBackup, monitor); - } - - private ITeamNode[] removeOutgoing(ITeamNode[] nodes) { - // no filter done yet - return nodes; - } - - /* - * If called on a new folder, the folder will become an outgoing addition. - */ - private void makeRemoteLocal(CVSRemoteSyncElement element, IProgressMonitor monitor) throws CVSException { - IRemoteResource remote = element.getRemote(); - final IResource local = element.getLocal(); - try { - if(remote==null) { - local.delete(false, monitor); - } else { - if(remote.isContainer()) { - if(!local.exists()) { - ((IFolder)local).create(false /*don't force*/, true /*local*/, monitor); - } - } 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 { - if (!localFile.getParent().exists()) { - ensureParentExists(localFile); - } - 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 void ensureParentExists(IResource resource) throws CoreException { - IContainer parent = resource.getParent(); - if (!parent.exists()) { - ensureParentExists(parent); - IFolder folder = (IFolder)parent; - folder.create(false, true, null); - } - } - /** - * @see MergeAction#getHelpContextID() - */ - protected String getHelpContextID() { - return IHelpContextIds.MERGE_UPDATE_ACTION; - } - -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/merge/UpdateWithForcedJoinAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/merge/UpdateWithForcedJoinAction.java deleted file mode 100644 index 3f8777a8d..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/merge/UpdateWithForcedJoinAction.java +++ /dev/null @@ -1,96 +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.merge; - - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.IRemoteSyncElement; -import org.eclipse.team.internal.ccvs.core.util.Assert; -import org.eclipse.team.internal.ccvs.ui.IHelpContextIds; -import org.eclipse.team.internal.ccvs.ui.repo.RepositoryManager; -import org.eclipse.team.internal.ccvs.ui.sync.CVSSyncCompareInput; -import org.eclipse.team.internal.ui.sync.ITeamNode; -import org.eclipse.team.internal.ui.sync.SyncSet; - -/* - * Used only in the merge editor. This action allows the user to select a single conflict and use - * the cvs update -j command to merge the changes. This is required because when building the - * sync tree for a merge the cvs command 'cvs -n update -j -j' does not tell us which files - * can be auto-merged. This action then allows the user to run the merge without having to - * individually select each difference and use the 'copy right to left' buttons. - */ -public class UpdateWithForcedJoinAction extends UpdateMergeAction { - public UpdateWithForcedJoinAction(CVSSyncCompareInput model, ISelectionProvider sp, String label, Shell shell) { - super(model, sp, label, shell); - } - - /* - * @see UpdateSyncAction#runUpdateDeep(ITeamNode[], RepositoryManager, IProgressMonitor) - */ - protected void runUpdateDeep(ITeamNode[] nodes, RepositoryManager manager, IProgressMonitor monitor) throws TeamException { - // cannot be called from this action - Assert.isTrue(false); - } - - /* - * @see UpdateSyncAction#runUpdateIgnoreLocalShallow(ITeamNode[], RepositoryManager, IProgressMonitor) - */ - protected void runUpdateIgnoreLocalShallow(ITeamNode[] nodes, RepositoryManager manager, IProgressMonitor monitor) throws TeamException { - // force an update -j -j to be called on the conflict - mergeWithLocal(nodes, manager, true, monitor); - } - - /* - * @see UpdateSyncAction#runUpdateShallow(ITeamNode[], RepositoryManager, IProgressMonitor) - */ - protected void runUpdateShallow(ITeamNode[] nodes, RepositoryManager manager, IProgressMonitor monitor) throws TeamException { - // cannot be called from this action - Assert.isTrue(false); - } - - /* - * @see MergeAction#isEnabled(ITeamNode) - */ - protected boolean isEnabled(ITeamNode node) { - int kind = node.getKind(); - if ((node.getChangeDirection() == IRemoteSyncElement.CONFLICTING) && - (kind & IRemoteSyncElement.AUTOMERGE_CONFLICT) == 0) { - return true; - } else { - return false; - } - } - /* - * @see UpdateSyncAction#promptForConflicts() - */ - protected boolean promptForConflicts() { - // don't prompt for overriding conflicts, because this action is simply merging and creating a backup copy of the original file. - return true; - } - - /* - * Override removeNonApplicableNodes because conflicting nodes should not be removed from this set. - */ - protected void removeNonApplicableNodes(SyncSet set, int syncMode) { - set.removeOutgoingNodes(); - set.removeIncomingNodes(); - } - /** - * @see MergeAction#getHelpContextID() - */ - protected String getHelpContextID() { - return IHelpContextIds.MERGE_UPDATE_WITH_JOIN_ACTION; - } - -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/AddSyncAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/AddSyncAction.java deleted file mode 100644 index aac0b1902..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/AddSyncAction.java +++ /dev/null @@ -1,143 +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.sync; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.compare.structuremergeviewer.Differencer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.StructuredSelection; -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.ICVSFile; -import org.eclipse.team.internal.ccvs.core.ICVSResource; -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.syncinfo.MutableResourceSyncInfo; -import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; -import org.eclipse.team.internal.ccvs.ui.IHelpContextIds; -import org.eclipse.team.internal.ccvs.ui.Policy; -import org.eclipse.team.internal.ccvs.ui.repo.RepositoryManager; -import org.eclipse.team.internal.ui.sync.ITeamNode; -import org.eclipse.team.internal.ui.sync.SyncSet; -import org.eclipse.team.internal.ui.sync.TeamFile; - -/** - * This is a CVS sync view action that will - */ -public class AddSyncAction extends MergeAction { - public AddSyncAction(CVSSyncCompareInput model, ISelectionProvider sp, String label, Shell shell) { - super(model, sp, label, shell); - } - - protected SyncSet run(SyncSet syncSet, IProgressMonitor monitor) { - boolean result = saveIfNecessary(); - if (!result) return null; - - ITeamNode[] changed = syncSet.getChangedNodes(); - if (changed.length == 0) { - return syncSet; - } - List additions = new ArrayList(); - - try { - for (int i = 0; i < changed.length; i++) { - int kind = changed[i].getKind(); - // leave the added nodes in the sync view. Their sync state - // won't change but the decoration should. - IResource resource = changed[i].getResource(); - if ((kind & Differencer.DIRECTION_MASK) == ITeamNode.CONFLICTING) { - if (resource.getType() == IResource.FOLDER) { - makeInSync(changed[i]); - } else { - makeAdded(changed[i]); - } - } else { - if (resource.getType() == IResource.FILE) { - additions.add(resource); - } - } - } - - RepositoryManager manager = CVSUIPlugin.getPlugin().getRepositoryManager(); - if (additions.size() != 0) { - manager.add((IResource[])additions.toArray(new IResource[0]), monitor); - } - - // for all files ensure that parent folders are made in sync after - // the add completes. - for (int i = 0; i < changed.length; i++) { - ITeamNode node = changed[i]; - IResource resource = changed[i].getResource(); - if (resource.getType() == IResource.FILE) { - syncSet.remove(node); - } - } - } catch (final TeamException e) { - handle(e); - return null; - } - - return syncSet; - } - - protected void makeAdded(ITeamNode changed) - throws TeamException, CVSException { - // Fake the add locally since add command will fail - makeInSync(changed.getParent()); - CVSRemoteSyncElement syncElement = (CVSRemoteSyncElement)((TeamFile)changed).getMergeResource().getSyncElement(); - ICVSResource remote = (ICVSResource)syncElement.getRemote(); - MutableResourceSyncInfo info = remote.getSyncInfo().cloneMutable(); - info.setTimeStamp(null); - info.setAdded(); - ICVSFile cvsFile = CVSWorkspaceRoot.getCVSFileFor((IFile)changed.getResource()); - cvsFile.setSyncInfo(info, ICVSFile.UNKNOWN); - } - - /** - * Enabled for folders and files that aren't added. - */ - protected boolean isEnabled(ITeamNode node) { - try { - CVSSyncSet set = new CVSSyncSet(new StructuredSelection(node)); - set.removeConflictingNodes(); - return set.hasNonAddedChanges(); - } catch (CVSException e) { - CVSUIPlugin.log(e); - return false; - } - } - - /** - * Remove all nodes that aren't files and folders that need to be added. - */ - protected void removeNonApplicableNodes(SyncSet set, int syncMode) { - set.removeIncomingNodes(); - set.removeConflictingNodes(); - ((CVSSyncSet)set).removeAddedChanges(); - } - /** - * @see MergeAction#getHelpContextID() - */ - protected String getHelpContextID() { - return IHelpContextIds.SYNC_ADD_ACTION; - } - - protected String getErrorTitle() { - return Policy.bind("AddAction.addFailed"); //$NON-NLS-1$ - } -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSCatchupReleaseViewer.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSCatchupReleaseViewer.java deleted file mode 100644 index 2b05f4192..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSCatchupReleaseViewer.java +++ /dev/null @@ -1,613 +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.sync; - - -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.compare.CompareConfiguration; -import org.eclipse.compare.structuremergeviewer.DiffContainer; -import org.eclipse.compare.structuremergeviewer.DiffElement; -import org.eclipse.compare.structuremergeviewer.DiffNode; -import org.eclipse.compare.structuremergeviewer.IDiffElement; -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.action.IMenuManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.IDecoration; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -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.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.team.core.RepositoryProvider; -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.CVSProviderPlugin; -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.ICVSRemoteFile; -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.syncinfo.ResourceSyncInfo; -import org.eclipse.team.internal.ccvs.ui.CVSLightweightDecorator; -import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; -import org.eclipse.team.internal.ccvs.ui.HistoryView; -import org.eclipse.team.internal.ccvs.ui.ICVSUIConstants; -import org.eclipse.team.internal.ccvs.ui.IHelpContextIds; -import org.eclipse.team.internal.ccvs.ui.OverlayIconCache; -import org.eclipse.team.internal.ccvs.ui.Policy; -import org.eclipse.team.internal.ccvs.ui.merge.OverrideUpdateMergeAction; -import org.eclipse.team.internal.ccvs.ui.merge.UpdateMergeAction; -import org.eclipse.team.internal.ccvs.ui.merge.UpdateWithForcedJoinAction; -import org.eclipse.team.internal.ui.OverlayIcon; -import org.eclipse.team.internal.ui.sync.CatchupReleaseViewer; -import org.eclipse.team.internal.ui.sync.ChangedTeamContainer; -import org.eclipse.team.internal.ui.sync.ITeamNode; -import org.eclipse.team.internal.ui.sync.MergeResource; -import org.eclipse.team.internal.ui.sync.SyncView; -import org.eclipse.team.internal.ui.sync.TeamFile; -import org.eclipse.ui.help.WorkbenchHelp; - -public class CVSCatchupReleaseViewer extends CatchupReleaseViewer { - // Actions - private UpdateSyncAction updateAction; - private ForceUpdateSyncAction forceUpdateAction; - - private CommitSyncAction commitAction; - private ForceCommitSyncAction forceCommitAction; - - private UpdateMergeAction updateMergeAction; - private UpdateWithForcedJoinAction updateWithJoinAction; - private OverrideUpdateMergeAction forceUpdateMergeAction; - - private IgnoreAction ignoreAction; - private HistoryAction showInHistory; - - private Action confirmMerge; - private AddSyncAction addAction; - - private Action selectAdditions; - private Image conflictImage; - - private static class DiffOverlayIcon extends OverlayIcon { - private static final int HEIGHT = 16; - private static final int WIDTH = 22; - public DiffOverlayIcon(Image baseImage, ImageDescriptor[] overlays, int[] locations) { - super(baseImage, overlays, locations, new Point(WIDTH, HEIGHT)); - } - protected void drawOverlays(ImageDescriptor[] overlays, int[] locations) { - Point size = getSize(); - for (int i = 0; i < overlays.length; i++) { - ImageDescriptor overlay = overlays[i]; - ImageData overlayData = overlay.getImageData(); - switch (locations[i]) { - case TOP_LEFT: - drawImage(overlayData, 0, 0); - break; - case TOP_RIGHT: - drawImage(overlayData, size.x - overlayData.width, 0); - break; - case BOTTOM_LEFT: - drawImage(overlayData, 0, size.y - overlayData.height); - break; - case BOTTOM_RIGHT: - drawImage(overlayData, size.x - overlayData.width, size.y - overlayData.height); - break; - } - } - } - } - - private static class HistoryAction extends Action implements ISelectionChangedListener { - IStructuredSelection selection; - public HistoryAction(String label) { - super(label); - } - public void run() { - if (selection.isEmpty()) { - return; - } - HistoryView view = HistoryView.openInActivePerspective(); - if (view == null) { - return; - } - ITeamNode node = (ITeamNode)selection.getFirstElement(); - IRemoteSyncElement remoteSyncElement = ((TeamFile)node).getMergeResource().getSyncElement(); - ICVSRemoteFile remoteFile = (ICVSRemoteFile)remoteSyncElement.getRemote(); - IResource local = remoteSyncElement.getLocal(); - - ICVSRemoteFile baseFile = (ICVSRemoteFile)remoteSyncElement.getBase(); - if(baseFile == null) { - try { - baseFile = (ICVSRemoteFile)CVSWorkspaceRoot.getRemoteResourceFor(local); - } catch (CVSException e) { - baseFile = null; - } - } - - if(local.exists()) { - view.showHistory(local); - }else if (baseFile != null) { - view.showHistory(baseFile); - } else if (remoteFile != null) { - view.showHistory(remoteFile); - } - } - public void selectionChanged(SelectionChangedEvent event) { - ISelection selection = event.getSelection(); - if (!(selection instanceof IStructuredSelection)) { - setEnabled(false); - return; - } - IStructuredSelection ss = (IStructuredSelection)selection; - if (ss.size() != 1) { - setEnabled(false); - return; - } - ITeamNode first = (ITeamNode)ss.getFirstElement(); - if (first instanceof TeamFile) { - // can only show history on elements that have a remote file - this.selection = ss; - IRemoteSyncElement remoteSyncElement = ((TeamFile)first).getMergeResource().getSyncElement(); - if(remoteSyncElement.getRemote() != null || remoteSyncElement.getBase() != null) { - setEnabled(true); - } else { - setEnabled(false); - } - } else { - this.selection = null; - setEnabled(false); - } - } - } - - public CVSCatchupReleaseViewer(Composite parent, CVSSyncCompareInput model) { - super(parent, model); - initializeActions(model); - initializeLabelProvider(); - // set F1 help - WorkbenchHelp.setHelp(this.getControl(), IHelpContextIds.CATCHUP_RELEASE_VIEWER); - } - - private static class Decoration implements IDecoration { - public String prefix = ""; //$NON-NLS-1$ - public String suffix = ""; //$NON-NLS-1$ - public ImageDescriptor overlay; - - /** - * @see org.eclipse.jface.viewers.IDecoration#addPrefix(java.lang.String) - */ - public void addPrefix(String prefix) { - this.prefix = prefix; - } - /** - * @see org.eclipse.jface.viewers.IDecoration#addSuffix(java.lang.String) - */ - public void addSuffix(String suffix) { - this.suffix = suffix; - } - /** - * @see org.eclipse.jface.viewers.IDecoration#addOverlay(org.eclipse.jface.resource.ImageDescriptor) - */ - public void addOverlay(ImageDescriptor overlay) { - this.overlay = overlay; - } - } - - private Image getConflictImage() { - if(conflictImage != null) - return conflictImage; - final ImageDescriptor conflictDescriptor = CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_MERGEABLE_CONFLICT); - conflictImage = conflictDescriptor.createImage(); - return conflictImage; - } - - - private void initializeLabelProvider() { - final LabelProvider oldProvider = (LabelProvider)getLabelProvider(); - - - setLabelProvider(new LabelProvider() { - private OverlayIconCache iconCache = new OverlayIconCache(); - - public void dispose() { - iconCache.disposeAll(); - oldProvider.dispose(); - if(conflictImage != null) - conflictImage.dispose(); - } - - public Image getImage(Object element) { - Image image = oldProvider.getImage(element); - - if (! (element instanceof ITeamNode)) - return image; - - ITeamNode node = (ITeamNode)element; - IResource resource = node.getResource(); - - if (! resource.exists()) - return image; - - CVSTeamProvider provider = (CVSTeamProvider)RepositoryProvider.getProvider(resource.getProject(), CVSProviderPlugin.getTypeId()); - List overlays = new ArrayList(); - List locations = new ArrayList(); - - // use the default cvs image decorations - ImageDescriptor resourceOverlay = CVSLightweightDecorator.getOverlay(node.getResource(),false, provider); - - int kind = node.getKind(); - boolean conflict = (kind & IRemoteSyncElement.AUTOMERGE_CONFLICT) != 0; - - if(resourceOverlay != null) { - overlays.add(resourceOverlay); - locations.add(new Integer(OverlayIcon.BOTTOM_RIGHT)); - } - - if(conflict) { - overlays.add(CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_MERGEABLE_CONFLICT)); - locations.add(new Integer(OverlayIcon.TOP_LEFT)); - } - - if (overlays.isEmpty()) { - return image; - } - - //combine the descriptors and return the resulting image - Integer[] integers = (Integer[])locations.toArray(new Integer[locations.size()]); - int[] locs = new int[integers.length]; - for (int i = 0; i < integers.length; i++) { - locs[i] = integers[i].intValue(); - } - - return iconCache.getImageFor(new DiffOverlayIcon(image, - (ImageDescriptor[]) overlays.toArray(new ImageDescriptor[overlays.size()]), - locs)); - } - - public String getText(Object element) { - String label = oldProvider.getText(element); - if (! (element instanceof ITeamNode)) - return label; - - ITeamNode node = (ITeamNode)element; - IResource resource = node.getResource(); - - if (resource.exists()) { - // use the default text decoration preferences - Decoration decoration = new Decoration(); - CVSLightweightDecorator.decorateTextLabel(resource, decoration, false /*don't show dirty*/, false /*don't show revisions*/); - label = decoration.prefix + label + decoration.suffix; - } - return label; - } - }); - } - - protected void fillContextMenu(IMenuManager manager) { - super.fillContextMenu(manager); - if (showInHistory != null) { - manager.add(showInHistory); - } - manager.add(new Separator()); - switch (getSyncMode()) { - case SyncView.SYNC_INCOMING: - updateAction.update(SyncView.SYNC_INCOMING); - manager.add(updateAction); - forceUpdateAction.update(SyncView.SYNC_INCOMING); - manager.add(forceUpdateAction); - manager.add(new Separator()); - confirmMerge.setEnabled(confirmMerge.isEnabled()); - manager.add(confirmMerge); - break; - case SyncView.SYNC_OUTGOING: - addAction.update(SyncView.SYNC_OUTGOING); - manager.add(addAction); - commitAction.update(SyncView.SYNC_OUTGOING); - manager.add(commitAction); - forceCommitAction.update(SyncView.SYNC_OUTGOING); - manager.add(forceCommitAction); - ignoreAction.update(); - manager.add(ignoreAction); - manager.add(new Separator()); - confirmMerge.setEnabled(confirmMerge.isEnabled()); - manager.add(confirmMerge); - selectAdditions.setEnabled(selectAdditions.isEnabled()); - manager.add(selectAdditions); - break; - case SyncView.SYNC_BOTH: - addAction.update(SyncView.SYNC_BOTH); - manager.add(addAction); - commitAction.update(SyncView.SYNC_BOTH); - manager.add(commitAction); - updateAction.update(SyncView.SYNC_BOTH); - manager.add(updateAction); - ignoreAction.update(); - manager.add(ignoreAction); - manager.add(new Separator()); - forceCommitAction.update(SyncView.SYNC_BOTH); - manager.add(forceCommitAction); - forceUpdateAction.update(SyncView.SYNC_BOTH); - manager.add(forceUpdateAction); - manager.add(new Separator()); - confirmMerge.setEnabled( confirmMerge.isEnabled()); - manager.add(confirmMerge); - break; - case SyncView.SYNC_MERGE: - updateMergeAction.update(SyncView.SYNC_INCOMING); - forceUpdateMergeAction.update(SyncView.SYNC_INCOMING); - updateWithJoinAction.update(SyncView.SYNC_INCOMING); - manager.add(updateMergeAction); - manager.add(forceUpdateMergeAction); - manager.add(updateWithJoinAction); - break; - } - } - - /** - * Creates the actions for this viewer. - */ - private void initializeActions(final CVSSyncCompareInput diffModel) { - Shell shell = getControl().getShell(); - commitAction = new CommitSyncAction(diffModel, this, Policy.bind("CVSCatchupReleaseViewer.commit"), shell); //$NON-NLS-1$ - forceCommitAction = new ForceCommitSyncAction(diffModel, this, Policy.bind("CVSCatchupReleaseViewer.forceCommit"), shell); //$NON-NLS-1$ - updateAction = new UpdateSyncAction(diffModel, this, Policy.bind("CVSCatchupReleaseViewer.update"), shell); //$NON-NLS-1$ - forceUpdateAction = new ForceUpdateSyncAction(diffModel, this, Policy.bind("CVSCatchupReleaseViewer.forceUpdate"), shell); //$NON-NLS-1$ - updateMergeAction = new UpdateMergeAction(diffModel, this, Policy.bind("CVSCatchupReleaseViewer.update"), shell); //$NON-NLS-1$ - ignoreAction = new IgnoreAction(diffModel, this, Policy.bind("CVSCatchupReleaseViewer.ignore"), shell); //$NON-NLS-1$ - updateWithJoinAction = new UpdateWithForcedJoinAction(diffModel, this, Policy.bind("CVSCatchupReleaseViewer.mergeUpdate"), shell); //$NON-NLS-1$ - forceUpdateMergeAction = new OverrideUpdateMergeAction(diffModel, this, Policy.bind("CVSCatchupReleaseViewer.forceUpdate"), shell); //$NON-NLS-1$ - addAction = new AddSyncAction(diffModel, this, Policy.bind("CVSCatchupReleaseViewer.addAction"), shell); //$NON-NLS-1$ - - // Show in history view - showInHistory = new HistoryAction(Policy.bind("CVSCatchupReleaseViewer.showInHistory")); //$NON-NLS-1$ - WorkbenchHelp.setHelp(showInHistory, IHelpContextIds.SHOW_IN_RESOURCE_HISTORY); - addSelectionChangedListener(showInHistory); - - selectAdditions = new Action(Policy.bind("CVSCatchupReleaseViewer.Select_&Outgoing_Additions_1"), null) { //$NON-NLS-1$ - public boolean isEnabled() { - DiffNode node = diffModel.getDiffRoot(); - IDiffElement[] elements = node.getChildren(); - for (int i = 0; i < elements.length; i++) { - IDiffElement element = elements[i]; - if (element instanceof ITeamNode) { - CVSSyncSet set = new CVSSyncSet(new StructuredSelection(element)); - try { - if (set.hasNonAddedChanges()) return true; - } catch (CVSException e) { - // Log the error and enable the menu item - CVSUIPlugin.log(e); - return true; - } - } else { - // unanticipated situation, just enable the action - return true; - } - } - return false; - } - public void run() { - List additions = new ArrayList(); - DiffNode root = diffModel.getDiffRoot(); - visit(root, additions); - setSelection(new StructuredSelection(additions)); - } - private void visit(IDiffElement node, List additions) { - try { - if (node instanceof TeamFile) { - TeamFile file = (TeamFile)node; - if (file.getChangeDirection() == IRemoteSyncElement.OUTGOING) { - if (file.getChangeType() == IRemoteSyncElement.ADDITION) { - ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(file.getResource()); - if (cvsResource.isManaged()) return; - additions.add(node); - } - } - return; - } - if (node instanceof ChangedTeamContainer) { - ChangedTeamContainer container = (ChangedTeamContainer)node; - if (container.getChangeDirection() == IRemoteSyncElement.OUTGOING) { - if (container.getChangeType() == IRemoteSyncElement.ADDITION) { - ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(container.getResource()); - if (!((ICVSFolder)cvsResource).isCVSFolder()) { - additions.add(node); - } - } - } - - } - if (node instanceof DiffContainer) { - IDiffElement[] children = ((DiffContainer)node).getChildren(); - for (int i = 0; i < children.length; i++) { - visit(children[i], additions); - } - } - } catch (TeamException e) { - CVSUIPlugin.log(e); - } - } - }; - WorkbenchHelp.setHelp(selectAdditions, IHelpContextIds.SELECT_NEW_RESOURCES_ACTION); - - // confirm merge - confirmMerge = new Action(Policy.bind("CVSCatchupReleaseViewer.confirmMerge"), null) { //$NON-NLS-1$ - public void run() { - ISelection s = getSelection(); - if (!(s instanceof IStructuredSelection) || s.isEmpty()) { - return; - } - List needsMerge = new ArrayList(); - for (Iterator it = ((IStructuredSelection)s).iterator(); it.hasNext();) { - final Object element = it.next(); - if(element instanceof DiffElement) { - mergeRecursive((IDiffElement)element, needsMerge); - } - } - TeamFile[] files = (TeamFile[]) needsMerge.toArray(new TeamFile[needsMerge.size()]); - if(files.length != 0) { - try { - for (int i = 0; i < files.length; i++) { - TeamFile teamFile = (TeamFile)files[i]; - CVSUIPlugin.getPlugin().getRepositoryManager().merged(new IRemoteSyncElement[] {teamFile.getMergeResource().getSyncElement()}); - teamFile.merged(); - } - } catch(TeamException e) { - CVSUIPlugin.openError(getControl().getShell(), null, null, e); - } - } - refresh(); - diffModel.updateStatusLine(); - } - - public boolean isEnabled() { - ISelection s = getSelection(); - if (!(s instanceof IStructuredSelection) || s.isEmpty()) { - return false; - } - for (Iterator it = ((IStructuredSelection)s).iterator(); it.hasNext();) { - Object element = (Object) it.next(); - if(element instanceof TeamFile) { - TeamFile file = (TeamFile)element; - int direction = file.getChangeDirection(); - int type = file.getChangeType(); - if(direction == IRemoteSyncElement.INCOMING || - direction == IRemoteSyncElement.CONFLICTING) { - continue; - } - } - return false; - } - return true; - } - }; - WorkbenchHelp.setHelp(confirmMerge, IHelpContextIds.CONFIRM_MERGE_ACTION); - } - - protected void mergeRecursive(IDiffElement element, List needsMerge) { - if (element instanceof DiffContainer) { - DiffContainer container = (DiffContainer)element; - IDiffElement[] children = container.getChildren(); - for (int i = 0; i < children.length; i++) { - mergeRecursive(children[i], needsMerge); - } - } else if (element instanceof TeamFile) { - TeamFile file = (TeamFile)element; - needsMerge.add(file); - } - } - - /** - * Provide CVS-specific labels for the editors. - */ - protected void updateLabels(MergeResource resource) { - CompareConfiguration config = getCompareConfiguration(); - String name = resource.getName(); - config.setLeftLabel(Policy.bind("CVSCatchupReleaseViewer.workspaceFile", name)); //$NON-NLS-1$ - - IRemoteSyncElement syncTree = resource.getSyncElement(); - IRemoteResource remote = syncTree.getRemote(); - if (remote != null) { - try { - final ICVSRemoteFile remoteFile = (ICVSRemoteFile)remote; - String revision = remoteFile.getRevision(); - final String[] author = new String[] { "" }; //$NON-NLS-1$ - try { - CVSUIPlugin.runWithProgress(getTree().getShell(), true /*cancelable*/, - new IRunnableWithProgress() { - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - try { - ILogEntry logEntry = remoteFile.getLogEntry(monitor); - if (logEntry != null) - author[0] = logEntry.getAuthor(); - } catch (TeamException e) { - throw new InvocationTargetException(e); - } - } - }); - } catch (InterruptedException e) { // ignore cancellation - } catch (InvocationTargetException e) { - Throwable t = e.getTargetException(); - if (t instanceof TeamException) { - throw (TeamException) t; - } - // should not get here - } - config.setRightLabel(Policy.bind("CVSCatchupReleaseViewer.repositoryFileRevision", new Object[] {name, revision, author[0]})); //$NON-NLS-1$ - } catch (TeamException e) { - CVSUIPlugin.openError(getControl().getShell(), null, null, e); - config.setRightLabel(Policy.bind("CVSCatchupReleaseViewer.repositoryFile", name)); //$NON-NLS-1$ - } - } else { - config.setRightLabel(Policy.bind("CVSCatchupReleaseViewer.noRepositoryFile")); //$NON-NLS-1$ - } - - IRemoteResource base = syncTree.getBase(); - if (base != null) { - try { - String revision = ((ICVSRemoteFile)base).getRevision(); - config.setAncestorLabel(Policy.bind("CVSCatchupReleaseViewer.commonFileRevision", new Object[] {name, revision} )); //$NON-NLS-1$ - } catch (TeamException e) { - CVSUIPlugin.openError(getControl().getShell(), null, null, e); - config.setRightLabel(Policy.bind("CVSCatchupReleaseViewer.commonFile", name)); //$NON-NLS-1$ - } - } else { - config.setAncestorLabel(Policy.bind("CVSCatchupReleaseViewer.noCommonFile")); //$NON-NLS-1$ - } - - IResource local = syncTree.getLocal(); - if (local != null) { - if (!local.exists()) { - config.setLeftLabel(Policy.bind("CVSCatchupReleaseViewer.No_workspace_file_1")); //$NON-NLS-1$ - } else { - ICVSFile cvsFile = CVSWorkspaceRoot.getCVSFileFor((IFile)local); - ResourceSyncInfo info = null; - try { - info = cvsFile.getSyncInfo(); - name = local.getName(); - String revision = null; - if (info != null) { - revision = info.getRevision(); - if (info.isAdded() || info.isDeleted()) { - revision = null; - } - } - if (revision != null) { - config.setLeftLabel(Policy.bind("CVSCatchupReleaseViewer.commonFileRevision", name, revision)); //$NON-NLS-1$ - } else { - config.setLeftLabel(Policy.bind("CVSCatchupReleaseViewer.commonFile", name)); //$NON-NLS-1$ - } - } catch (CVSException e) { - CVSUIPlugin.openError(getControl().getShell(), null, null, e); - config.setLeftLabel(Policy.bind("CVSCatchupReleaseViewer.commonFile", name)); //$NON-NLS-1$ - } - } - } - } -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSSyncCompareInput.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSSyncCompareInput.java deleted file mode 100644 index 3a4cfe016..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSSyncCompareInput.java +++ /dev/null @@ -1,415 +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.sync; - - -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.eclipse.compare.structuremergeviewer.Differencer; -import org.eclipse.compare.structuremergeviewer.ICompareInput; -import org.eclipse.compare.structuremergeviewer.IDiffContainer; -import org.eclipse.compare.structuremergeviewer.IDiffElement; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.team.core.RepositoryProvider; -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.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.ICVSResource; -import org.eclipse.team.internal.ccvs.core.resources.CVSRemoteSyncElement; -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.Policy; -import org.eclipse.team.internal.ui.sync.CatchupReleaseViewer; -import org.eclipse.team.internal.ui.sync.ChangedTeamContainer; -import org.eclipse.team.internal.ui.sync.ITeamNode; -import org.eclipse.team.internal.ui.sync.SyncCompareInput; -import org.eclipse.team.internal.ui.sync.SyncSet; -import org.eclipse.team.internal.ui.sync.TeamFile; - -public class CVSSyncCompareInput extends SyncCompareInput { - - private IResource[] resources; - private boolean onlyOutgoing = false; - - public CVSSyncCompareInput(IResource[] resources) { - this(resources, false); - } - - protected CVSSyncCompareInput(IResource[] resources, int granularity) { - super(granularity); - this.resources = getNonOverlapping(resources); - } - - public CVSSyncCompareInput(IResource[] resources, boolean onlyOutgoing) { - super(CVSUIPlugin.getPlugin().getPreferenceStore().getBoolean(ICVSUIConstants.PREF_CONSIDER_CONTENTS) ? ILocalSyncElement.GRANULARITY_CONTENTS : ILocalSyncElement.GRANULARITY_TIMESTAMP); - this.onlyOutgoing = onlyOutgoing; - this.resources = getNonOverlapping(resources); - } - - /** - * Method getNonOverlapping ensures that a resource is not covered more than once. - * @param resources - * @return IResource[] - */ - private IResource[] getNonOverlapping(IResource[] resources) { - // Sort the resources so the shortest paths are first - List sorted = new ArrayList(); - sorted.addAll(Arrays.asList(resources)); - Collections.sort(sorted, new Comparator() { - public int compare(Object arg0, Object arg1) { - IResource resource0 = (IResource) arg0; - IResource resource1 = (IResource) arg1; - return resource0.getFullPath().segmentCount() - resource1.getFullPath().segmentCount(); - } - public boolean equals(Object arg0) { - return false; - } - }); - // Collect all non-overlapping resources - List coveredPaths = new ArrayList(); - for (Iterator iter = sorted.iterator(); iter.hasNext();) { - IResource resource = (IResource) iter.next(); - IPath resourceFullPath = resource.getFullPath(); - boolean covered = false; - for (Iterator it = coveredPaths.iterator(); it.hasNext();) { - IPath path = (IPath) it.next(); - if(path.isPrefixOf(resourceFullPath)) { - covered = true; - } - } - if (covered) { - // if the resource is covered by a parent, remove it - iter.remove(); - } else { - // if the resource is a non-covered folder, add it to the covered paths - if (resource.getType() == IResource.FOLDER) { - coveredPaths.add(resource.getFullPath()); - } - } - } - return (IResource[]) sorted.toArray(new IResource[sorted.size()]); - } - - /** - * Overridden to create a custom DiffTreeViewer in the top left pane of the CompareProvider. - * - * Subclasses must create and return a new CatchupReleaseViewer, and set the viewer - * using setViewer(). - */ - public Viewer createDiffViewer(Composite parent) { - CatchupReleaseViewer catchupReleaseViewer = new CVSCatchupReleaseViewer(parent, this); - setViewer(catchupReleaseViewer); -// catchupReleaseViewer.getTree().addMouseMoveListener(new MouseMoveListener() { -// /** -// * @see MouseMoveListener#mouseMove(MouseEvent) -// */ -// public void mouseMove(MouseEvent e) { -// final Tree tree = (Tree)e.widget; -// TreeItem item = tree.getItem(new Point(e.x, e.y)); -// final TeamFile file; -// if (item != null) { -// // Hack: this is the only way to get an item from the tree viewer -// Object o = item.getData(); -// if (o instanceof TeamFile) { -// file = (TeamFile)o; -// } else file = null; -// } else file = null; -// -// // avoid redundant updates -- identity test is good enough here -// if (file == previousTeamFile) return; -// previousTeamFile = file; -// getShell().getDisplay().asyncExec(new Runnable() { -// public void run() { -// updateToolTip(tree, file); -// } -// }); -// } -// }); - return catchupReleaseViewer; - } - -// protected void updateToolTip(Tree tree, TeamFile file) { -// String newText = null; -// if (file != null && file.getChangeDirection() != ITeamNode.OUTGOING) { -// IRemoteSyncElement element = file.getMergeResource().getSyncElement(); -// final ICVSRemoteFile remoteFile = (ICVSRemoteFile)element.getRemote(); -// final ILogEntry[] logEntry = new ILogEntry[1]; -// if (remoteFile != null) { -// try { -// CVSUIPlugin.runWithProgress(getViewer().getTree().getShell(), true /*cancelable*/, -// new IRunnableWithProgress() { -// public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { -// try { -// logEntry[0] = remoteFile.getLogEntry(monitor); -// } catch (TeamException ex) { -// throw new InvocationTargetException(ex); -// } -// } -// }); -// } catch (InterruptedException ex) { -// // ignore cancellation -// } catch (InvocationTargetException ex) { -// // ignore the exception -// } -// } -// if (logEntry[0] != null) { -// newText = logEntry[0].getComment(); -// } -// } -// if (tree.isDisposed()) return; -// String oldText = tree.getToolTipText(); -// if (newText == oldText || newText != null && newText.equals(oldText)) return; -// tree.setToolTipText(newText); -// } - - protected IRemoteSyncElement[] createSyncElements(IProgressMonitor monitor) throws TeamException { - // Ensure that the projects for all resources being synchronized exist - // Note: this could happen on a refresh view after a synced project was deleted. - for (int i = 0; i < resources.length; i++) { - IResource resource = resources[i]; - if (!resource.getProject().exists()) { - throw new CVSException(Policy.bind("CVSSyncCompareInput.projectDeleted", resource.getProject().getName())); //$NON-NLS-1$ - } - } - - monitor.beginTask(null, 1000 + (onlyOutgoing?10:0)); - IResource[] resourcesToSync; - if (onlyOutgoing) { - List filteredResources = Arrays.asList(resources); - filteredResources = filterOutgoingChangesSet(filteredResources, Policy.subMonitorFor(monitor, 10)); - resourcesToSync = (IResource[]) filteredResources.toArray(new IResource[filteredResources.size()]); - } else { - resourcesToSync = resources; - } - return buildSyncTrees(resourcesToSync, Policy.subMonitorFor(monitor, 1000)); - } - - private IRemoteSyncElement[] buildSyncTrees(IResource[] resourcesToSync, IProgressMonitor monitor)throws TeamException { - IRemoteSyncElement[] trees = new IRemoteSyncElement[resourcesToSync.length]; - int work = 1000 * resourcesToSync.length; - monitor.beginTask(null, work); - try { - for (int i = 0; i < trees.length; i++) { - trees[i] = CVSWorkspaceRoot.getRemoteSyncTree(resourcesToSync[i], null, Policy.subMonitorFor(monitor, 1000)); - } - } finally { - monitor.done(); - } - return trees; - } - - protected void updateView() { - // Update the view - if (getDiffRoot().hasChildren()) { - getViewer().refresh(); - } else { - getViewer().setInput(null); - } - - // Update the status line - updateStatusLine(); - } - - /** - * Overridden to mark the source as merged. - */ - protected void compareInputChanged(ICompareInput source) { - super.compareInputChanged(source); - updateView(); - - // prompt user with warning - Shell shell = getShell(); - if(shell != null) { - // prompt - if(source instanceof TeamFile) { - TeamFile file = (TeamFile)source; - int direction = file.getChangeDirection(); - int type = file.getChangeType(); - if(direction == IRemoteSyncElement.INCOMING || - direction == IRemoteSyncElement.CONFLICTING) { - promptForConfirmMerge(getShell()); - } - } - } - } - - /* - * Helper method to get cvs elements from the selection in the sync editor input - */ - public static CVSRemoteSyncElement getSyncElementFrom(Object node) { - CVSRemoteSyncElement element = null; - if (node instanceof TeamFile) { - element = (CVSRemoteSyncElement)((TeamFile)node).getMergeResource().getSyncElement(); - } else if (node instanceof ChangedTeamContainer) { - element = (CVSRemoteSyncElement)((ChangedTeamContainer)node).getMergeResource().getSyncElement(); - } - return element; - } - - /* - * Returns the resources in this input. - */ - public IResource[] getResources() { - return resources; - } - - /* - * Inform user that when changes are merged in the sync view that confirm - * merge should be called to finish the merge. - */ - private void promptForConfirmMerge(final Shell shell) { - final IPreferenceStore store = CVSUIPlugin.getPlugin().getPreferenceStore(); - if(!store.getBoolean(ICVSUIConstants.PREF_PROMPT_ON_SAVING_IN_SYNC)) { - return; - }; - shell.getDisplay().syncExec(new Runnable() { - public void run() { - AvoidableMessageDialog dialog = new AvoidableMessageDialog( - shell, - Policy.bind("CVSSyncCompareInput.confirmMergeMessageTitle"), //$NON-NLS-1$ - null, // accept the default window icon - Policy.bind("CVSSyncCompareInput.confirmMergeMessage"), //$NON-NLS-1$ - MessageDialog.INFORMATION, - new String[] {IDialogConstants.OK_LABEL}, - 0); - dialog.open(); - if(dialog.isDontShowAgain()) { - store.setValue(ICVSUIConstants.PREF_PROMPT_ON_SAVING_IN_SYNC, false); - } - } - }); - } - - /** - * Wrap the input preparation in a CVS session run so open sessions will be reused and - * file contents under the same remote root folder will be fetched using the same connection. - * - * Also run with refresh prompting if one of the resources is out of sync with the local - * file system. - */ - public Object prepareInput(IProgressMonitor pm) throws InterruptedException, InvocationTargetException { - final Object[] result = new Object[] { null }; - CVSUIPlugin.runWithRefresh(getShell(), resources, new IRunnableWithProgress() { - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - result[0] = CVSSyncCompareInput.super.prepareInput(monitor); - } - }, pm); - - if (hasDifferences(result[0])) { - return result[0]; - } else { - return null; - } - } - - /** - * The given object has differences if it is an IDiffElement with a change - * or it is an IDiffContainer that contains differences. - * - * @param object - * @return boolean - */ - private boolean hasDifferences(Object object) { - if (object instanceof IDiffElement) { - IDiffElement element = (IDiffElement)object; - if (element.getKind() != Differencer.NO_CHANGE) return true; - if (object instanceof IDiffContainer) { - IDiffContainer container = (IDiffContainer) object; - if (container.hasChildren()) { - IDiffElement[] children = container.getChildren(); - for (int i = 0; i < children.length; i++) { - IDiffElement child = children[i]; - if (hasDifferences(child)) return true; - } - } - } - } - return false; - } - - private boolean hasIncomingChanges(ChangedTeamContainer container) { - IDiffElement[] children = container.getChildren(); - for (int i = 0; i < children.length; i++) { - IDiffElement element = children[i]; - int direction = element.getKind() & Differencer.DIRECTION_MASK; - if (direction == ITeamNode.CONFLICTING || direction == ITeamNode.INCOMING) { - return true; - } - if (element instanceof ChangedTeamContainer) { - boolean hasIncomingChanges = hasIncomingChanges((ChangedTeamContainer)element); - if (hasIncomingChanges) return true; - } - } - return false; - } - - /* - * Method copied from TeamAction. It should be put in a common place - */ - protected Map getProviderMapping(IResource[] resources) { - Map result = new HashMap(); - for (int i = 0; i < resources.length; i++) { - RepositoryProvider provider = RepositoryProvider.getProvider(resources[i].getProject()); - List list = (List)result.get(provider); - if (list == null) { - list = new ArrayList(); - result.put(provider, list); - } - list.add(resources[i]); - } - return result; - } - - protected SyncSet getSyncSet(IStructuredSelection selection) { - return new CVSSyncSet(selection); - } - - /* - * Return the resources from the original list that are modified. - */ - private List filterOutgoingChangesSet(List resources, IProgressMonitor monitor) throws CVSException { - try { - monitor.beginTask(null, 100 * resources.size()); - monitor.subTask(Policy.bind("CVSSyncCompareInput.filteringOutgoingChanges")); //$NON-NLS-1$ - List result = new ArrayList(); - for (Iterator iter = resources.iterator(); iter.hasNext();) { - IResource resource = (IResource) iter.next(); - ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource); - if (!cvsResource.isIgnored() && cvsResource.isModified(Policy.subMonitorFor(monitor, 100))) - result.add(resource); - } - return result; - } finally { - monitor.done(); - } - } -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSSyncCompareUnsharedInput.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSSyncCompareUnsharedInput.java deleted file mode 100644 index 7d81f80d3..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSSyncCompareUnsharedInput.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.ccvs.ui.sync; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -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.ICVSRepositoryLocation; -import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; -import org.eclipse.team.internal.ccvs.ui.Policy; - -public class CVSSyncCompareUnsharedInput extends CVSSyncCompareInput { - - private ICVSRepositoryLocation location; - private String moduleName; - private CVSTag tag; - - public CVSSyncCompareUnsharedInput(IProject project, ICVSRepositoryLocation location, String moduleName, CVSTag tag) { - super(new IResource[] { project }); - this.location = location; - this.moduleName = moduleName; - this.tag = tag; - } - - protected IRemoteSyncElement[] createSyncElements(IProgressMonitor monitor) throws TeamException { - IResource[] resources = getResources(); - IRemoteSyncElement[] trees = new IRemoteSyncElement[resources.length]; - int work = 1000 * resources.length; - monitor.beginTask(null, work); - try { - for (int i = 0; i < trees.length; i++) { - trees[i] = CVSWorkspaceRoot.getRemoteSyncTree((IProject)resources[i], location, moduleName, tag, Policy.subMonitorFor(monitor, 1000)); - } - } finally { - monitor.done(); - } - return trees; - } -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSSyncSet.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSSyncSet.java deleted file mode 100644 index aec6b7a32..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSSyncSet.java +++ /dev/null @@ -1,209 +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.sync; - - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.core.resources.IResource; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.team.core.sync.IRemoteSyncElement; -import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.ICVSFolder; -import org.eclipse.team.internal.ccvs.core.ICVSResource; -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.internal.ui.sync.ITeamNode; -import org.eclipse.team.internal.ui.sync.SyncSet; - -/** - * This class contains a set of CVS resources that are slated to be - * synchronized. This adds CVS specific handling to the common sync set - * class, specifically to deal with non-added outgoing changes. - */ -public class CVSSyncSet extends SyncSet { - - /** - * Creates a new sync set on the nodes in the given selection. - */ - public CVSSyncSet(IStructuredSelection nodeSelection) { - super(nodeSelection); - } - - public ITeamNode[] getNonAddedNodes() throws CVSException { - List result = new ArrayList(); - ITeamNode[] changedNodes = getChangedNodes(); - for (int i = 0; i < changedNodes.length; i++) { - ITeamNode node = changedNodes[i]; - ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(node.getResource()); - if (cvsResource.isFolder()) { - if (!((ICVSFolder)cvsResource).isCVSFolder()) { - result.add(node); - } - } else if (!cvsResource.isManaged()) { - result.add(node); - } - } - return (ITeamNode[])result.toArray(new ITeamNode[result.size()]); - } - - public boolean hasNonAddedChanges() throws CVSException { - ITeamNode[] changedNodes = getChangedNodes(); - for (int i = 0; i < changedNodes.length; i++) { - ITeamNode node = changedNodes[i]; - ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(node.getResource()); - if (cvsResource.exists()) { - if (cvsResource.isFolder()) { - if (!((ICVSFolder)cvsResource).isCVSFolder()) { - return true; - } - } else if (!cvsResource.isManaged()) { - return true; - } - } - } - return false; - } - - public boolean removeNonAddedChanges() { - for (Iterator it = getSyncSet().iterator(); it.hasNext();) { - try { - ITeamNode node = (ITeamNode)it.next(); - ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(node.getResource()); - if (cvsResource.exists()) { - if(cvsResource.isFolder()) { - if(!((ICVSFolder)cvsResource).isCVSFolder()) { - it.remove(); - } - } else { - if(!cvsResource.isManaged()) { - it.remove(); - } - } - } - } catch (CVSException e) { - // isManaged or isCVSFolder threw an exception - // Log it and continue - CVSUIPlugin.log(e); - } - } - return false; - } - - public boolean removeNonAddedResources(IResource[] remove) { - for (Iterator it = getSyncSet().iterator(); it.hasNext();) { - ITeamNode node = (ITeamNode)it.next(); - IResource resource = node.getResource(); - boolean included = false; - for (int j = 0; j < remove.length; j++) { - IResource resourceToRemove = remove[j]; - if (resource.equals(resourceToRemove)) { - included = true; - break; - } - } - if (included) - it.remove(); - } - return false; - } - - public boolean removeAddedChanges() { - for (Iterator it = getSyncSet().iterator(); it.hasNext();) { - try { - ITeamNode node = (ITeamNode)it.next(); - ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(node.getResource()); - if(cvsResource.isFolder()) { - if(((ICVSFolder)cvsResource).isCVSFolder()) { - it.remove(); - } - } else { - if(cvsResource.isManaged()) { - it.remove(); - } - } - } catch (CVSException e) { - // isManaged or isCVSFolder threw an exception - // Log it and continue - CVSUIPlugin.log(e); - } - } - return false; - } - - /** - * Returns a message for the status line describing this sync set. - * - * Override the method in SyncSet to add information about new resources - */ - public String getStatusLineMessage() { - int incoming = 0; - int outgoing = 0; - int conflicts = 0; - int newResources = 0; - ITeamNode[] nodes = getChangedNodes(); - for (int i = 0; i < nodes.length; i++) { - ITeamNode next = nodes[i]; - switch (next.getChangeDirection()) { - case IRemoteSyncElement.INCOMING: - incoming++; - break; - case IRemoteSyncElement.OUTGOING: - outgoing++; - ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(next.getResource()); - try { - if (cvsResource.exists()) { - if (cvsResource.isFolder()) { - if (!((ICVSFolder)cvsResource).isCVSFolder()) { - newResources++; - } - } else if (!cvsResource.isManaged()) { - newResources++; - } - } - } catch (CVSException e) { - CVSUIPlugin.log(e); - } - break; - case IRemoteSyncElement.CONFLICTING: - conflicts++; - break; - } - } - StringBuffer result = new StringBuffer(); - - if (conflicts == 0) { - result.append(Policy.bind("CVSSyncSet.noConflicts")); //$NON-NLS-1$ - } else { - result.append(Policy.bind("CVSSyncSet.conflicts", new Object[] {Integer.toString(conflicts)} )); //$NON-NLS-1$ - } - if (incoming == 0) { - result.append(Policy.bind("CVSSyncSet.noIncomings")); //$NON-NLS-1$ - } else { - result.append(Policy.bind("CVSSyncSet.incomings", new Object[] {Integer.toString(incoming)} )); //$NON-NLS-1$ - } - if (outgoing == 0) { - result.append(Policy.bind("CVSSyncSet.noOutgoings")); //$NON-NLS-1$ - } else { - result.append(Policy.bind("CVSSyncSet.outgoings", new Object[] {Integer.toString(outgoing)} )); //$NON-NLS-1$ - } - if (newResources == 0) { - result.append(Policy.bind("CVSSyncSet.noNew")); //$NON-NLS-1$ - } else { - result.append(Policy.bind("CVSSyncSet.new", new Object[] {Integer.toString(newResources)} )); //$NON-NLS-1$ - } - - return result.toString(); - } -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CommitSyncAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CommitSyncAction.java deleted file mode 100644 index 08703dd84..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CommitSyncAction.java +++ /dev/null @@ -1,46 +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.sync; - -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.team.internal.ccvs.ui.IHelpContextIds; -import org.eclipse.team.internal.ui.sync.ITeamNode; -import org.eclipse.team.internal.ui.sync.SyncSet; - -/** - * Override ForceCommitSyncAction to only work on outgoing nodes - */ -public class CommitSyncAction extends ForceCommitSyncAction { - public CommitSyncAction(CVSSyncCompareInput model, ISelectionProvider sp, String label, Shell shell) { - super(model, sp, label, shell); - } - - protected boolean isEnabled(ITeamNode node) { - // The commit action is enabled only for non-conflicting outgoing changes - CVSSyncSet set = new CVSSyncSet(new StructuredSelection(node)); - return set.hasOutgoingChanges(); - } - - protected void removeNonApplicableNodes(SyncSet set, int syncMode) { - set.removeConflictingNodes(); - set.removeIncomingNodes(); - } - /** - * @see MergeAction#getHelpContextID() - */ - protected String getHelpContextID() { - return IHelpContextIds.SYNC_COMMIT_ACTION; - } - -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/ForceCommitSyncAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/ForceCommitSyncAction.java deleted file mode 100644 index c4bd759b3..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/ForceCommitSyncAction.java +++ /dev/null @@ -1,366 +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.sync; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -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.ResourcesPlugin; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.widgets.Shell; -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.ICVSRunnable; -import org.eclipse.team.internal.ccvs.core.resources.CVSRemoteSyncElement; -import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; -import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; -import org.eclipse.team.internal.ccvs.ui.IHelpContextIds; -import org.eclipse.team.internal.ccvs.ui.Policy; -import org.eclipse.team.internal.ccvs.ui.repo.RepositoryManager; -import org.eclipse.team.internal.ui.sync.ChangedTeamContainer; -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.internal.ui.sync.TeamFile; - -public class ForceCommitSyncAction extends MergeAction { - public ForceCommitSyncAction(CVSSyncCompareInput model, ISelectionProvider sp, String label, Shell shell) { - super(model, sp, label, shell); - } - - protected SyncSet run(SyncSet syncSet, IProgressMonitor monitor) { - boolean result = saveIfNecessary(); - if (!result) return null; - - // If there is a conflict in the syncSet, we need to prompt the user before proceeding. - if (syncSet.hasConflicts() || syncSet.hasIncomingChanges()) { - switch (promptForConflicts(syncSet)) { - case 0: - // Yes, synchronize conflicts as well - break; - case 1: - // No, only synchronize non-conflicting changes. - syncSet.removeConflictingNodes(); - syncSet.removeIncomingNodes(); - break; - case 2: - default: - // Cancel - return null; - } - } - ITeamNode[] changed = syncSet.getChangedNodes(); - if (changed.length == 0) { - return syncSet; - } - - // accumulate any resources that are not under version control - IResource[] unadded = null; - if (syncSet instanceof CVSSyncSet) { - CVSSyncSet cvsSyncSet = (CVSSyncSet)syncSet; - try { - if (cvsSyncSet.hasNonAddedChanges()) { - ITeamNode[] nodes = cvsSyncSet.getNonAddedNodes(); - unadded = new IResource[nodes.length]; - for (int i = 0; i < nodes.length; i++) { - unadded[i] = nodes[i].getResource(); - } - } - } catch (CVSException e) { - CVSUIPlugin.log(e); - } - } - - // prompt to get comment and any resources to be added to version control - final RepositoryManager manager = CVSUIPlugin.getPlugin().getRepositoryManager(); - IResource[] toBeAdded = promptForResourcesToBeAdded(manager, unadded); - if (toBeAdded == null) return null; // User cancelled. - final String comment = promptForComment(manager, syncSet.getResources()); - if (comment == null) return null; // User cancelled. - - // remove unshared resources that were not selected by the user - if (unadded != null && unadded.length > 0) { - List resourcesToRemove = new ArrayList(unadded.length); - for (int i = 0; i < unadded.length; i++) { - IResource unaddedResource = unadded[i]; - boolean included = false; - for (int j = 0; j < toBeAdded.length; j++) { - IResource resourceToAdd = toBeAdded[j]; - if (unaddedResource.equals(resourceToAdd)) { - included = true; - break; - } - } - if (!included) - resourcesToRemove.add(unaddedResource); - } - CVSSyncSet cvsSyncSet = (CVSSyncSet)syncSet; - cvsSyncSet.removeNonAddedResources((IResource[]) resourcesToRemove.toArray(new IResource[resourcesToRemove.size()])); - changed = syncSet.getChangedNodes(); - if (changed.length == 0) { - return syncSet; - } - } - - final List commits = new ArrayList(); - final List additions = new ArrayList(); - final List deletions = new ArrayList(); - final List toMerge = new ArrayList(); - final List incoming = new ArrayList(); - - // A list of diff elements in the sync set which are incoming folder additions - final List parentCreationElements = new ArrayList(); - // A list of diff elements in the sync set which are folder conflicts - final List parentConflictElements = new ArrayList(); - - for (int i = 0; i < changed.length; i++) { - int kind = changed[i].getKind(); - IResource resource = changed[i].getResource(); - if (resource.getType() == IResource.FILE) { - commits.add(resource); - } - IDiffContainer parent = changed[i].getParent(); - if (parent != null) { - int parentKind = changed[i].getParent().getKind(); - if (((parentKind & Differencer.CHANGE_TYPE_MASK) == Differencer.ADDITION) && - ((parentKind & Differencer.DIRECTION_MASK) == ITeamNode.INCOMING)) { - parentCreationElements.add(parent); - } else if ((parentKind & Differencer.DIRECTION_MASK) == ITeamNode.CONFLICTING) { - parentConflictElements.add(parent); - } - } - switch (kind & Differencer.DIRECTION_MASK) { - case ITeamNode.INCOMING: - // Incoming change. Make it outgoing before committing. - incoming.add(changed[i]); - break; - case ITeamNode.OUTGOING: - switch (kind & Differencer.CHANGE_TYPE_MASK) { - case Differencer.ADDITION: - // Outgoing addition. 'add' it before committing. - additions.add(resource); - break; - case Differencer.DELETION: - // Outgoing deletion. 'delete' it before committing. - deletions.add(resource); - break; - case Differencer.CHANGE: - // Outgoing change. Just commit it. - break; - } - break; - case ITeamNode.CONFLICTING: - if (changed[i] instanceof TeamFile) { - toMerge.add(((TeamFile)changed[i]).getMergeResource().getSyncElement()); - } - break; - } - } - try { - // execute the operations in a single CVS runnable so sync changes are batched - CVSWorkspaceRoot.getCVSFolderFor(ResourcesPlugin.getWorkspace().getRoot()).run( - new ICVSRunnable() { - public void run(IProgressMonitor monitor) throws CVSException { - try { - if (parentCreationElements.size() > 0) { - // If a node has a parent that is an incoming folder creation, we have to - // create that folder locally and set its sync info before we can get the - // node itself. We must do this for all incoming folder creations (recursively) - // in the case where there are multiple levels of incoming folder creations. - Iterator it = parentCreationElements.iterator(); - while (it.hasNext()) { - makeInSync((IDiffElement)it.next()); - } - } - if (parentConflictElements.size() > 0) { - // If a node has a parent that is a folder conflict, that means that the folder - // exists locally but has no sync info. In order to get the node, we have to - // create the sync info for the folder (and any applicable parents) before we - // get the node itself. - Iterator it = parentConflictElements.iterator(); - while (it.hasNext()) { - makeInSync((IDiffElement)it.next()); - } - } - - // Handle any real incomming deletions by unmanaging them before adding - Iterator it = incoming.iterator(); - Set incomingDeletions = new HashSet(incoming.size()); - while (it.hasNext()) { - ITeamNode node = (ITeamNode)it.next(); - collectIncomingDeletions(node, incomingDeletions, monitor); - if ((node instanceof TeamFile) && !additions.contains(node)) { - CVSRemoteSyncElement element = (CVSRemoteSyncElement)((TeamFile)node).getMergeResource().getSyncElement(); - element.makeOutgoing(monitor); - } - } - it = incomingDeletions.iterator(); - while (it.hasNext()) { - ITeamNode node = (ITeamNode)it.next(); - CVSRemoteSyncElement syncElement; - if (node instanceof TeamFile) { - syncElement = (CVSRemoteSyncElement)((TeamFile)node).getMergeResource().getSyncElement(); - } else { - syncElement = (CVSRemoteSyncElement)((ChangedTeamContainer)node).getMergeResource().getSyncElement(); - } - additions.add(syncElement.getLocal()); - CVSWorkspaceRoot.getCVSResourceFor(syncElement.getLocal()).unmanage(null); - } - - if (additions.size() != 0) { - manager.add((IResource[])additions.toArray(new IResource[0]), monitor); - } - if (deletions.size() != 0) { - manager.delete((IResource[])deletions.toArray(new IResource[0]), monitor); - } - if (toMerge.size() != 0) { - manager.merged((IRemoteSyncElement[])toMerge.toArray(new IRemoteSyncElement[0])); - } - manager.commit((IResource[])commits.toArray(new IResource[commits.size()]), comment, monitor); - } catch (TeamException e) { - throw CVSException.wrapException(e); - } - } - }, monitor); - } catch (CVSException e) { - handle(e); - return null; - } - - return syncSet; - } - - protected boolean isEnabled(ITeamNode node) { - // The force commit action is enabled only for conflicting and incoming changes - CVSSyncSet set = new CVSSyncSet(new StructuredSelection(node)); - if (syncMode == SyncView.SYNC_OUTGOING) { - return (set.hasConflicts() && hasRealChanges(node, new int[] { ITeamNode.CONFLICTING })); - } else { - return ((set.hasIncomingChanges() || set.hasConflicts()) && hasRealChanges(node, new int[] { ITeamNode.CONFLICTING, ITeamNode.INCOMING })); - } - } - - /** - * Prompts the user to determine how conflicting changes should be handled. - * Note: This method is designed to be overridden by test cases. - * @return 0 to sync conflicts, 1 to sync all non-conflicts, 2 to cancel - */ - protected int promptForConflicts(SyncSet syncSet) { - String[] buttons = new String[] {IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.CANCEL_LABEL}; - String question = Policy.bind("CommitSyncAction.questionRelease"); //$NON-NLS-1$ - String title = Policy.bind("CommitSyncAction.titleRelease"); //$NON-NLS-1$ - String[] tips = new String[] { - Policy.bind("CommitSyncAction.releaseAll"), //$NON-NLS-1$ - Policy.bind("CommitSyncAction.releasePart"), //$NON-NLS-1$ - Policy.bind("CommitSyncAction.cancelRelease") //$NON-NLS-1$ - }; - Shell shell = getShell(); - final ToolTipMessageDialog dialog = new ToolTipMessageDialog(shell, title, null, question, MessageDialog.QUESTION, buttons, tips, 0); - shell.getDisplay().syncExec(new Runnable() { - public void run() { - dialog.open(); - } - }); - return dialog.getReturnCode(); - } - - /** - * Prompts the user for a release comment. - * Note: This method is designed to be overridden by test cases. - * @return the comment, or null to cancel - */ - protected String promptForComment(RepositoryManager manager, IResource[] resourcesToCommit) { - return manager.promptForComment(getShell(), resourcesToCommit); - } - - protected IResource[] promptForResourcesToBeAdded(RepositoryManager manager, IResource[] unadded) { - return manager.promptForResourcesToBeAdded(getShell(), unadded); - } - - protected void removeNonApplicableNodes(SyncSet set, int syncMode) { - set.removeOutgoingNodes(); - if (syncMode != SyncView.SYNC_BOTH) { - set.removeIncomingNodes(); - } - } - - /* - * Handle incoming folder deletion. - * - * Special handling is required in the case were a folder has been deleted remotely - * (i.e using "rm -rf" on the server). - * - * We need to determine if there is a remote folder corresponding to this folder - * If there isn't, we need to unmanage the local resource and then add the folder - * Unfortunately, unmanaging may effect the state of the children which are also incoming deletions - */ - private void collectIncomingDeletions(ITeamNode node, Set additions, IProgressMonitor monitor) throws TeamException { - if (isIncomingDeletion(node) && ! additions.contains(node) && ! existsRemotely(node, monitor)) { - - // Make sure that the parent is handled - IDiffContainer parent = node.getParent(); - if (isIncomingDeletion((ITeamNode)parent)) { - collectIncomingDeletions((ITeamNode)parent, additions, monitor); - } - - // Add the node to the list - additions.add(node); - } - } - - private boolean isIncomingDeletion(ITeamNode node) { - return (node.getChangeDirection() == ITeamNode.INCOMING && node.getChangeType() == Differencer.DELETION); - } - - /* - * For files, use the remote of the sync element to determine whether there is a remote or not. - * For folders, if there is no remote in the tree check remotely in case the folder was pruned - */ - private boolean existsRemotely(ITeamNode node, IProgressMonitor monitor) throws TeamException { - - CVSRemoteSyncElement syncElement; - if (node instanceof TeamFile) { - syncElement = (CVSRemoteSyncElement)((TeamFile)node).getMergeResource().getSyncElement(); - } else { - syncElement = (CVSRemoteSyncElement)((ChangedTeamContainer)node).getMergeResource().getSyncElement(); - } - if (syncElement.getRemote() != null) { - return true; - } - if (syncElement.getLocal().getType() == IResource.FILE) { - return false; - } - return CVSWorkspaceRoot.getRemoteResourceFor(syncElement.getLocal()).exists(monitor); - } - /** - * @see MergeAction#getHelpContextID() - */ - protected String getHelpContextID() { - return IHelpContextIds.SYNC_FORCED_COMMIT_ACTION; - } - - protected String getErrorTitle() { - return Policy.bind("CommitAction.commitFailed"); //$NON-NLS-1$ - } -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/ForceUpdateSyncAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/ForceUpdateSyncAction.java deleted file mode 100644 index bd3b02042..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/ForceUpdateSyncAction.java +++ /dev/null @@ -1,51 +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.sync; - -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.team.internal.ccvs.ui.IHelpContextIds; -import org.eclipse.team.internal.ui.sync.ITeamNode; -import org.eclipse.team.internal.ui.sync.SyncSet; -import org.eclipse.team.internal.ui.sync.SyncView; - -public class ForceUpdateSyncAction extends UpdateSyncAction { - - public ForceUpdateSyncAction(CVSSyncCompareInput model, ISelectionProvider sp, String label, Shell shell) { - super(model, sp, label, shell); - } - - protected boolean isEnabled(ITeamNode node) { - // The force update action is enabled only for conflicting and outgoing changes - SyncSet set = new SyncSet(new StructuredSelection(node)); - if (syncMode == SyncView.SYNC_INCOMING) { - return (set.hasConflicts() && hasRealChanges(node, new int[] { ITeamNode.CONFLICTING })); - } else { - return ((set.hasOutgoingChanges() || set.hasConflicts()) && hasRealChanges(node, new int[] { ITeamNode.CONFLICTING, ITeamNode.OUTGOING })); - } - } - - protected void removeNonApplicableNodes(SyncSet set, int syncMode) { - set.removeIncomingNodes(); - if (syncMode != SyncView.SYNC_BOTH) { - set.removeOutgoingNodes(); - } - } - - /** - * @see MergeAction#getHelpContextID() - */ - protected String getHelpContextID() { - return IHelpContextIds.SYNC_FORCED_UPDATE_ACTION; - } - -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/IgnoreAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/IgnoreAction.java deleted file mode 100644 index 61036eca1..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/IgnoreAction.java +++ /dev/null @@ -1,134 +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.sync; - - -import org.eclipse.compare.structuremergeviewer.IDiffContainer; -import org.eclipse.compare.structuremergeviewer.IDiffElement; -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.team.core.sync.IRemoteSyncElement; -import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.core.ICVSResource; -import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; -import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; -import org.eclipse.team.internal.ccvs.ui.IHelpContextIds; -import org.eclipse.team.internal.ccvs.ui.IgnoreResourcesDialog; -import org.eclipse.team.internal.ui.sync.ChangedTeamContainer; -import org.eclipse.team.internal.ui.sync.ITeamNode; -import org.eclipse.team.internal.ui.sync.SyncSet; -import org.eclipse.team.internal.ui.sync.TeamFile; -import org.eclipse.team.internal.ui.sync.UnchangedTeamContainer; -import org.eclipse.ui.help.WorkbenchHelp; - -public class IgnoreAction extends Action { - Shell shell; - private CVSSyncCompareInput diffModel; - private ISelectionProvider selectionProvider; - - public IgnoreAction(CVSSyncCompareInput model, ISelectionProvider sp, String label, Shell shell) { - super(label); - this.shell = shell; - this.diffModel = model; - this.selectionProvider = sp; - WorkbenchHelp.setHelp(this, IHelpContextIds.SYNC_IGNORE_ACTION); - } - public void run() { - IStructuredSelection selection = (IStructuredSelection)selectionProvider.getSelection(); - if (selection.isEmpty()) return; - // Do the update - Object first = selection.getFirstElement(); - ICVSResource cvsResource = null; - IResource resource = null; - if (first instanceof TeamFile) { - resource = ((TeamFile)first).getMergeResource().getResource(); - cvsResource = CVSWorkspaceRoot.getCVSFileFor((IFile) resource); - } else if (first instanceof ChangedTeamContainer) { - resource = ((ChangedTeamContainer)first).getMergeResource().getResource(); - cvsResource = CVSWorkspaceRoot.getCVSFolderFor((IContainer) resource); - } - if (resource != null) { - try { - IgnoreResourcesDialog dialog = new IgnoreResourcesDialog(shell, new IResource[] {resource}); - if (dialog.open() != IgnoreResourcesDialog.OK) return; - String pattern = dialog.getIgnorePatternFor(resource); - cvsResource.setIgnoredAs(pattern); - } catch (CVSException e) { - CVSUIPlugin.openError(shell, null, null, e); - return; - } - removeNodes(new SyncSet(selection).getChangedNodes()); - diffModel.refresh(); - } - } - /** - * Enabled if only one item is selected and it is an outgoing addition. - * - * This may be a folder or a single file, which will be handled differently. - */ - protected boolean isEnabled(Object[] nodes) { - if (nodes.length != 1) return false; - if (!(nodes[0] instanceof ITeamNode)) return false; - ITeamNode node = (ITeamNode)nodes[0]; - if (node.getKind() != (ITeamNode.OUTGOING | IRemoteSyncElement.ADDITION)) return false; - IResource resource = node.getResource(); - ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource); - try { - if (cvsResource.isManaged()) return false; - if (cvsResource.isIgnored()) return false; - } catch (CVSException e) { - CVSUIPlugin.log(e); - return false; - } - return true; - } - public void update() { - IStructuredSelection selection = (IStructuredSelection)selectionProvider.getSelection(); - setEnabled(isEnabled(selection.toArray())); - } - /** - * The given nodes have been synchronized. Remove them from - * the sync set. - */ - private void removeNodes(final ITeamNode[] nodes) { - // Update the model - for (int i = 0; i < nodes.length; i++) { - if (nodes[i].getClass() == UnchangedTeamContainer.class) { - // Unchanged containers get removed automatically when all - // children are removed - continue; - } - if (nodes[i].getClass() == ChangedTeamContainer.class) { - // If this node still has children, convert to an - // unchanged container, then it will disappear when - // all children have been removed. - ChangedTeamContainer container = (ChangedTeamContainer)nodes[i]; - IDiffElement[] children = container.getChildren(); - if (children.length > 0) { - IDiffContainer parent = container.getParent(); - UnchangedTeamContainer unchanged = new UnchangedTeamContainer(parent, container.getResource()); - for (int j = 0; j < children.length; j++) { - unchanged.add(children[j]); - } - parent.removeToRoot(container); - continue; - } - // No children, it will get removed below. - } - nodes[i].getParent().removeToRoot(nodes[i]); - } - } -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/MergeAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/MergeAction.java deleted file mode 100644 index ec67075f3..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/MergeAction.java +++ /dev/null @@ -1,369 +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.sync; - - -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -import org.eclipse.compare.ITypedElement; -import org.eclipse.compare.structuremergeviewer.Differencer; -import org.eclipse.compare.structuremergeviewer.IDiffContainer; -import org.eclipse.compare.structuremergeviewer.IDiffElement; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.dialogs.ProgressMonitorDialog; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.IRemoteSyncElement; -import org.eclipse.team.internal.ccvs.core.ICVSFolder; -import org.eclipse.team.internal.ccvs.core.resources.CVSRemoteSyncElement; -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.internal.ui.sync.ChangedTeamContainer; -import org.eclipse.team.internal.ui.sync.ITeamNode; -import org.eclipse.team.internal.ui.sync.SyncSet; -import org.eclipse.team.internal.ui.sync.UnchangedTeamContainer; -import org.eclipse.ui.actions.WorkspaceModifyOperation; -import org.eclipse.ui.help.WorkbenchHelp; - -/** - * Applies merge related actions to the selected ITeamNodes. - */ -abstract class MergeAction extends Action { - public static final int CHECKIN = 0; - public static final int GET = 1; - public static final int DELETE_REMOTE = 2; - public static final int DELETE_LOCAL = 3; - - private CVSSyncCompareInput diffModel; - private ISelectionProvider selectionProvider; - - protected int syncMode; - private Shell shell; - - /** - * Creates a MergeAction which works on selection and doesn't commit changes. - */ - public MergeAction(CVSSyncCompareInput model, ISelectionProvider sp, String label, Shell shell) { - super(label); - this.diffModel = model; - this.selectionProvider = sp; - this.shell = shell; - String helpContextId = getHelpContextID(); - if (helpContextId != null) { - WorkbenchHelp.setHelp(this, helpContextId); - } - } - - /** - * Method getHelpContextID. - * @return String - */ - protected String getHelpContextID() { - return null; - } - - protected Shell getShell() { - return shell; - } - - protected CVSSyncCompareInput getDiffModel() { - return diffModel; - } - - /** - * Returns true if at least one node can perform the specified action. - */ - private boolean isEnabled(Object[] nodes) { - for (int i = 0; i < nodes.length; i++) { - if (nodes[i] instanceof ITeamNode) { - ITeamNode node = (ITeamNode)nodes[i]; - if (isEnabled(node)) { - return true; - } - } else { - if (nodes[i] instanceof IDiffContainer) - if (isEnabled(((IDiffContainer)nodes[i]).getChildren())) - return true; - } - } - return false; - } - - protected abstract boolean isEnabled(ITeamNode node); - - /** - * Perform the sychronization operation. - */ - public void run() { - ISelection s = selectionProvider.getSelection(); - if (!(s instanceof IStructuredSelection) || s.isEmpty()) { - return; - } - final SyncSet set = new CVSSyncSet((IStructuredSelection)s); - removeNonApplicableNodes(set, syncMode); - final SyncSet[] result = new SyncSet[1]; - WorkspaceModifyOperation op = new WorkspaceModifyOperation() { - public void execute(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - result[0] = MergeAction.this.run(set, monitor); - } - }; - try { - run(op); - } catch (InterruptedException e) { - } - if (result[0] != null) { - // all returned nodes that have a changed sync kind are assumed - // to have been operated on and will be removed from the diff tree. - removeNodes(result[0].getChangedNodes()); - - // any node that claims that it's IN_SYNC will be automatically - // filtered from the diff tree - see DiffElement.setKind(). - diffModel.updateView(); - } - } - - protected abstract void removeNonApplicableNodes(SyncSet set, int syncMode); - - /** - * The given nodes have been synchronized. Remove them from - * the sync set. - * - * For folders that are outgoing deletions, we may need to leave the - * folder as is or adjust the sync kind depending on the sync kind of - * the folder's children. - * - * @see CVSSyncCompareInput#collectResourceChanges(IDiffContainer, IRemoteSyncElement, IProgressMonitor) - */ - private void removeNodes(final ITeamNode[] nodes) { - // Update the model - Set outgoingFolderDeletions = new HashSet(); - for (int i = 0; i < nodes.length; i++) { - if (nodes[i].getClass() == UnchangedTeamContainer.class) { - // Unchanged containers get removed automatically when all - // children are removed - continue; - } - if (nodes[i].getClass() == ChangedTeamContainer.class) { - // If this node still has children, convert to an - // unchanged container, then it will disappear when - // all children have been removed. - ChangedTeamContainer container = (ChangedTeamContainer)nodes[i]; - IDiffElement[] children = container.getChildren(); - if (children.length > 0) { - if (isLocallyDeletedFolder(container)) { - // For locally deleted folders, we postpone the handling until all other children are removed - outgoingFolderDeletions.add(container); - } else { - IDiffContainer parent = container.getParent(); - UnchangedTeamContainer unchanged = new UnchangedTeamContainer(parent, container.getResource()); - for (int j = 0; j < children.length; j++) { - unchanged.add(children[j]); - } - parent.removeToRoot(container); - } - continue; - } - // No children, it will get removed below. - } else if (nodes[i].getParent().getClass() == ChangedTeamContainer.class) { - // If the parent is a locally deleted folder, we may want to update it's sync state as well - if (isLocallyDeletedFolder(nodes[i].getParent())) { - outgoingFolderDeletions.add(nodes[i].getParent()); - } - } - nodes[i].getParent().removeToRoot(nodes[i]); - } - // Remove any locally deleted folders from the sync tree as appropriate - for (Iterator iter = outgoingFolderDeletions.iterator(); iter.hasNext();) { - removeLocallyDeletedFolder((ChangedTeamContainer)iter.next()); - } - } - - /** - * Updates the action with the latest selection, setting enablement - * as necessary. - */ - public void update(int syncMode) { - this.syncMode = syncMode; - IStructuredSelection selection = (IStructuredSelection)selectionProvider.getSelection(); - setEnabled(isEnabled(selection.toArray())); - } - - /** - * Subclasses must implement this method, which performs action-specific code. - * - * It may return the sync set which was passed in, or null. - */ - protected abstract SyncSet run(SyncSet syncSet, IProgressMonitor monitor); - - /** - * Helper method to run a runnable in a progress monitor dialog, and display any errors. - */ - protected void run(IRunnableWithProgress op) throws InterruptedException { - ProgressMonitorDialog dialog = new ProgressMonitorDialog(getShell()); - try { - dialog.run(true, true, op); - } catch (InvocationTargetException e) { - handle(e); - } - } - - /** - * Helper method. Check if a save is necessary. If it is, prompt the user to save. - * Return true if all necessary saves have been performed, false otherwise. - */ - protected boolean saveIfNecessary() { - return getDiffModel().saveIfNecessary(); - } - - /** - * Answer true if the given diff element represents a locally deleted CVS folder. - * The sync state of locally deleted CVS folders is either outgoing deletion or - * conflicting change. - */ - protected boolean isLocallyDeletedFolder(IDiffElement element) { - if ( ! (element.getType() == IDiffElement.FOLDER_TYPE)) return false; - int kind = element.getKind(); - return (((kind & Differencer.CHANGE_TYPE_MASK) == Differencer.DELETION) && - ((kind & Differencer.DIRECTION_MASK) == ITeamNode.OUTGOING)) - || (((kind & Differencer.CHANGE_TYPE_MASK) == Differencer.CHANGE) && - ((kind & Differencer.DIRECTION_MASK) == ITeamNode.CONFLICTING)); - } - - /** - * Recreate any parents that are outgoing folder deletions - */ - protected void recreateLocallyDeletedFolder(IDiffElement element) throws TeamException { - // Recursively make the parent element (and its parents) in sync. - // Walk up and find the parents which need to be made in sync too. (For - // each parent that doesn't already have sync info). - if (element == null) return; - if (element instanceof ChangedTeamContainer) { - CVSRemoteSyncElement syncElement = (CVSRemoteSyncElement)((ChangedTeamContainer)element).getMergeResource().getSyncElement(); - // recreate the folder - ICVSFolder cvsFolder = (ICVSFolder) CVSWorkspaceRoot.getCVSResourceFor(syncElement.getLocal()); - if (! cvsFolder.exists()) { - recreateLocallyDeletedFolder(element.getParent()); - cvsFolder.mkdir(); - syncElement.makeInSync(Policy.monitorFor(null)); - ((ChangedTeamContainer)element).makeInSync(); - } - } - } - - /** - * Adjust the sync kind of the locally deleted folder and remove - * the folder if it doesn't contain any real changes - */ - private void removeLocallyDeletedFolder(ChangedTeamContainer container) { - boolean hasIncoming = hasRealChanges(container, new int[] { ITeamNode.INCOMING }); - boolean hasOutgoing = hasRealChanges(container, new int[] { ITeamNode.OUTGOING }); - boolean hasConflicting = hasRealChanges(container, new int[] { ITeamNode.CONFLICTING }); - IDiffContainer parent = container.getParent(); - if (hasConflicting || (hasOutgoing && hasIncoming)) { - // Leave as a conflict - return; - } else if (hasOutgoing) { - // Convert to an outgoing deletion - container.setKind(ITeamNode.OUTGOING | Differencer.DELETION); - } else if (hasIncoming) { - container.setKind(ITeamNode.INCOMING | Differencer.ADDITION); - } else { - // The folder is empty, remove it - if (parent != null) { - parent.removeToRoot(container); - } - } - // The parent may need adjusting as well - if (parent != null && isLocallyDeletedFolder(parent)) { - removeLocallyDeletedFolder((ChangedTeamContainer)parent); - } - } - - /** - * Look for real changes of the given type. Real changes are those that - * are not locally deleted folders that are persisted as phantoms - * to report local file deletions to the server. - */ - protected boolean hasRealChanges(IDiffElement node, int[] changeDirections) { - // For regular nodes (i.e. not local folder deletions), check the sync kind of the node - if ( ! isLocallyDeletedFolder(node)) { - int direction = node.getKind() & Differencer.DIRECTION_MASK; - for (int i = 0; i < changeDirections.length; i++) { - if (direction == changeDirections[i]) { - return true; - } - } - } - // For folders, check their children (if we didn't get a match above) - if (node.getType() == ITypedElement.FOLDER_TYPE) { - IDiffElement[] children = ((IDiffContainer)node).getChildren(); - for (int i = 0; i < children.length; i++) { - if (hasRealChanges(children[i], changeDirections)) { - return true; - } - } - } - // If no matches occured above, we don't have any "real" changes in the given directions - return false; - } - - /** - * Recursively make the parent element (and its parents) in sync. - * Walk up and find the parents which need to be made in sync too. (For - * each parent that doesn't already have sync info). - */ - protected void makeInSync(IDiffElement parentElement) throws TeamException { - ArrayList v = new ArrayList(); - int parentKind = parentElement.getKind(); - int direction = parentKind & Differencer.DIRECTION_MASK; - int change = parentKind & Differencer.CHANGE_TYPE_MASK; - while ((change == Differencer.ADDITION) && - ((direction == ITeamNode.INCOMING) || (direction == ITeamNode.CONFLICTING))) { - v.add(0, parentElement); - parentElement = parentElement.getParent(); - parentKind = parentElement == null ? 0 : parentElement.getKind(); - direction = parentKind & Differencer.DIRECTION_MASK; - change = parentKind & Differencer.CHANGE_TYPE_MASK; - } - Iterator parentIt = v.iterator(); - while (parentIt.hasNext()) { - IDiffElement next = (IDiffElement)parentIt.next(); - if (next instanceof ChangedTeamContainer) { - CVSRemoteSyncElement syncElement = (CVSRemoteSyncElement)((ChangedTeamContainer)next).getMergeResource().getSyncElement(); - // Create the sync info - syncElement.makeInSync(Policy.monitorFor(null)); - ((ChangedTeamContainer)next).setKind(IRemoteSyncElement.IN_SYNC); - } - } - } - - /** - * Sycn actions seem to need to be sync-execed to work - * @param t - */ - protected void handle(Throwable t) { - CVSUIPlugin.openError(getShell(), getErrorTitle(), null, t, CVSUIPlugin.PERFORM_SYNC_EXEC | CVSUIPlugin.LOG_NONTEAM_EXCEPTIONS); - } - - protected String getErrorTitle() { - return null; - } -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/UpdateSyncAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/UpdateSyncAction.java deleted file mode 100644 index b21efeb22..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/UpdateSyncAction.java +++ /dev/null @@ -1,430 +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.sync; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.eclipse.compare.structuremergeviewer.Differencer; -import org.eclipse.compare.structuremergeviewer.IDiffContainer; -import org.eclipse.compare.structuremergeviewer.IDiffElement; -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.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.StructuredSelection; -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.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.Shell; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.IRemoteSyncElement; -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.CVSRemoteSyncElement; -import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; -import org.eclipse.team.internal.ccvs.ui.IHelpContextIds; -import org.eclipse.team.internal.ccvs.ui.Policy; -import org.eclipse.team.internal.ccvs.ui.repo.RepositoryManager; -import org.eclipse.team.internal.ui.sync.ITeamNode; -import org.eclipse.team.internal.ui.sync.SyncSet; -import org.eclipse.team.internal.ui.sync.TeamFile; - -/** - * UpdateSyncAction is run on a set of sync nodes when the "Update" menu item is performed - * in the Synchronize view. - * - * This class is also used as the super class of the merge update actions for regular and forced - * update. - */ -public class UpdateSyncAction extends MergeAction { - public static class ConfirmDialog extends MessageDialog { - - private boolean autoMerge = true; - private Button radio1; - private Button radio2; - - public ConfirmDialog(Shell parentShell) { - super( - parentShell, - Policy.bind("UpdateSyncAction.Conflicting_changes_found_1"), //$NON-NLS-1$ - null, // accept the default window icon - Policy.bind("UpdateSyncAction.You_have_local_changes_you_are_about_to_overwrite_2"), //$NON-NLS-1$ - MessageDialog.QUESTION, - new String[] {IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, - 0); // yes is the default - } - - protected Control createCustomArea(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setLayout(new GridLayout()); - radio1 = new Button(composite, SWT.RADIO); - radio1.addSelectionListener(selectionListener); - - radio1.setText(Policy.bind("UpdateSyncAction.Only_update_resources_that_can_be_automatically_merged_3")); //$NON-NLS-1$ - - radio2 = new Button(composite, SWT.RADIO); - radio2.addSelectionListener(selectionListener); - - radio2.setText(Policy.bind("UpdateSyncAction.Update_all_resources,_overwriting_local_changes_with_remote_contents_4")); //$NON-NLS-1$ - - // set initial state - radio1.setSelection(autoMerge); - radio2.setSelection(!autoMerge); - - return composite; - } - - private SelectionListener selectionListener = new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - Button button = (Button)e.widget; - if (button.getSelection()) { - autoMerge = (button == radio1); - } - } - }; - - public boolean getAutomerge() { - return autoMerge; - } - } - - public UpdateSyncAction(CVSSyncCompareInput model, ISelectionProvider sp, String label, Shell shell) { - super(model, sp, label, shell); - } - - protected SyncSet run(final SyncSet syncSet, IProgressMonitor monitor) { - boolean result = saveIfNecessary(); - if (!result) return null; - - // If there are conflicts or outgoing changes in the syncSet, we need to warn the user. - boolean onlyUpdateAutomergeable = false; - if (syncSet.hasConflicts() || syncSet.hasOutgoingChanges()) { - if (syncSet.hasAutoMergeableConflicts()) { - switch (promptForMergeableConflicts()) { - case 0: // cancel - return null; - case 1: // only update auto-mergeable conflicts - onlyUpdateAutomergeable = true; - syncSet.removeNonMergeableNodes(); - break; - case 2: // update all conflicts - onlyUpdateAutomergeable = false; - break; - } - } else { - if (! promptForConflicts()) return null; - } - } - - ITeamNode[] changed = syncSet.getChangedNodes(); - if (changed.length == 0) { - return syncSet; - } - - List updateIgnoreLocalShallow = new ArrayList(); - List updateDeep = new ArrayList(); - List updateShallow = new ArrayList(); - - // A list of diff elements in the sync set which are incoming folder additions - Set parentCreationElements = new HashSet(); - // A list of diff elements in the sync set which are folder conflicts - Set parentConflictElements = new HashSet(); - // A list of diff elements in the sync set which are outgoing folder deletions - Set parentDeletionElements = new HashSet(); - // A list of the team nodes that we need to perform makeIncoming on - List makeIncoming = new ArrayList(); - // A list of diff elements that are incoming deletions. - // We do these first to avoid case conflicts - List updateDeletions = new ArrayList(); - // A list of diff elements that need to be unmanaged and locally deleted - List deletions = new ArrayList(); - - for (int i = 0; i < changed.length; i++) { - IDiffContainer parent = changed[i].getParent(); - if (parent != null) { - int parentKind = changed[i].getParent().getKind(); - if (((parentKind & Differencer.CHANGE_TYPE_MASK) == Differencer.ADDITION) && - ((parentKind & Differencer.DIRECTION_MASK) == ITeamNode.INCOMING)) { - parentCreationElements.add(parent); - } else if (isLocallyDeletedFolder(parent)) { - parentDeletionElements.add(parent); - } else if ((parentKind & Differencer.DIRECTION_MASK) == ITeamNode.CONFLICTING) { - parentConflictElements.add(parent); - } - } - ITeamNode changedNode = changed[i]; - IResource resource = changedNode.getResource(); - int kind = changedNode.getKind(); - switch (kind & Differencer.DIRECTION_MASK) { - case ITeamNode.INCOMING: - switch (kind & Differencer.CHANGE_TYPE_MASK) { - case Differencer.ADDITION: - updateIgnoreLocalShallow.add(changedNode); - break; - case Differencer.DELETION: - updateDeletions.add(changedNode); - break; - case Differencer.CHANGE: - updateDeep.add(changedNode); - break; - } - break; - case ITeamNode.OUTGOING: - switch (kind & Differencer.CHANGE_TYPE_MASK) { - case Differencer.ADDITION: - // Unmanage the file if necessary and delete it. - deletions.add(changedNode); - break; - case Differencer.DELETION: - if (resource.getType() == IResource.FILE) { - makeIncoming.add(changedNode); - updateDeep.add(changedNode); - } - break; - case Differencer.CHANGE: - updateIgnoreLocalShallow.add(changedNode); - break; - } - break; - case ITeamNode.CONFLICTING: - switch (kind & Differencer.CHANGE_TYPE_MASK) { - case Differencer.ADDITION: - if(changedNode instanceof IDiffContainer) { - parentConflictElements.add(changedNode); - } else { - makeIncoming.add(changedNode); - deletions.add(changedNode); - updateIgnoreLocalShallow.add(changedNode); - } - break; - case Differencer.DELETION: - // Doesn't happen, these nodes don't appear in the tree. - break; - case Differencer.CHANGE: - if (resource.getType() == IResource.FILE) { - // Depends on the flag. - if (onlyUpdateAutomergeable && (changedNode.getKind() & IRemoteSyncElement.AUTOMERGE_CONFLICT) != 0) { - updateShallow.add(changedNode); - } else { - // Check to see if there is a remote - if (((TeamFile)changedNode).getMergeResource().getSyncElement().getRemote() == null) { - // If a locally modified file has no remote, "update -C" will fail. - // We must unmanage and delete the file ourselves - deletions.add(changedNode); - } else { - updateIgnoreLocalShallow.add(changedNode); - // If the resource doesn't exist remotely, we must ensure the sync info will allow the above update. - if (!resource.exists()) { - makeIncoming.add(changedNode); - } - } - } - } else { - // Conflicting change on a folder only occurs if the folder has been deleted locally - // The folder should only be recreated if there were children in the changed set. - // Such folders would have been added to the parentDeletionElements set above - } - break; - } - break; - } - } - try { - // Calculate the total amount of work needed - int work = (makeIncoming.size() + deletions.size() + updateDeletions.size() + updateShallow.size() + updateIgnoreLocalShallow.size() + updateDeep.size()) * 100; - monitor.beginTask(null, work); - - RepositoryManager manager = CVSUIPlugin.getPlugin().getRepositoryManager(); - if (parentDeletionElements.size() > 0) { - // If a node has a parent that is an outgoing folder deletion, we have to - // recreate that folder locally (it's sync info already exists locally). - // We must do this for all outgoing folder deletions (recursively) - // in the case where there are multiple levels of outgoing folder deletions. - Iterator it = parentDeletionElements.iterator(); - while (it.hasNext()) { - recreateLocallyDeletedFolder((IDiffElement)it.next()); - } - } - if (parentCreationElements.size() > 0) { - // If a node has a parent that is an incoming folder creation, we have to - // create that folder locally and set its sync info before we can get the - // node itself. We must do this for all incoming folder creations (recursively) - // in the case where there are multiple levels of incoming folder creations. - Iterator it = parentCreationElements.iterator(); - while (it.hasNext()) { - IDiffElement element = (IDiffElement)it.next(); - makeInSync(element); - // Remove the folder from the update shallow list since we have it locally now - updateIgnoreLocalShallow.remove(element); - } - } - if (parentConflictElements.size() > 0) { - // If a node has a parent that is a folder conflict, that means that the folder - // exists locally but has no sync info. In order to get the node, we have to - // create the sync info for the folder (and any applicable parents) before we - // get the node itself. - Iterator it = parentConflictElements.iterator(); - while (it.hasNext()) { - makeInSync((IDiffElement)it.next()); - } - } - // Make any outgoing changes or deletions into incoming changes before updating. - Iterator it = makeIncoming.iterator(); - while (it.hasNext()) { - ITeamNode node = (ITeamNode)it.next(); - CVSRemoteSyncElement element = CVSSyncCompareInput.getSyncElementFrom(node); - element.makeIncoming(Policy.subMonitorFor(monitor, 100)); - } - - // Outgoing additions or conflicts with incoming deletions must be unmanaged and locally deleted. - if (deletions.size() > 0) { - runLocalDeletions((ITeamNode[])deletions.toArray(new ITeamNode[deletions.size()]), manager, Policy.subMonitorFor(monitor, deletions.size() * 100)); - } - - if (updateDeletions.size() > 0) { - runUpdateDeletions((ITeamNode[])updateDeletions.toArray(new ITeamNode[updateDeletions.size()]), manager, Policy.subMonitorFor(monitor, updateDeletions.size() * 100)); - } - if (updateShallow.size() > 0) { - runUpdateShallow((ITeamNode[])updateShallow.toArray(new ITeamNode[updateShallow.size()]), manager, Policy.subMonitorFor(monitor, updateShallow.size() * 100)); - } - if (updateIgnoreLocalShallow.size() > 0) { - runUpdateIgnoreLocalShallow((ITeamNode[])updateIgnoreLocalShallow.toArray(new ITeamNode[updateIgnoreLocalShallow.size()]), manager, Policy.subMonitorFor(monitor, updateIgnoreLocalShallow.size() * 100)); - } - if (updateDeep.size() > 0) { - runUpdateDeep((ITeamNode[])updateDeep.toArray(new ITeamNode[updateDeep.size()]), manager, Policy.subMonitorFor(monitor, updateDeep.size() * 100)); - } - } catch (final TeamException e) { - handle(e); - return null; - } catch (final CoreException e) { - handle(e); - return null; - } finally { - monitor.done(); - } - return syncSet; - } - - /** - * Method deleteAndKeepHistory. - * @param iResource - * @param iProgressMonitor - */ - protected void deleteAndKeepHistory(IResource resource, IProgressMonitor monitor) throws CoreException { - if (resource.getType() == IResource.FILE) - ((IFile)resource).delete(false /* force */, true /* keep history */, monitor); - else - resource.delete(false /* force */, monitor); - } - - protected void runLocalDeletions(ITeamNode[] nodes, RepositoryManager manager, IProgressMonitor monitor) throws TeamException, CoreException { - monitor.beginTask(null, nodes.length * 100); - for (int i = 0; i < nodes.length; i++) { - ITeamNode node = nodes[i]; - CVSRemoteSyncElement element = CVSSyncCompareInput.getSyncElementFrom(node); - element.makeIncoming(Policy.subMonitorFor(monitor, 50)); - deleteAndKeepHistory(element.getLocal(), Policy.subMonitorFor(monitor, 50)); - } - monitor.done(); - } - - protected void runUpdateDeletions(ITeamNode[] nodes, RepositoryManager manager, IProgressMonitor monitor) throws TeamException { - manager.update(getIResourcesFrom(nodes), new Command.LocalOption[] { Command.DO_NOT_RECURSE }, false, monitor); - } - - protected void runUpdateDeep(ITeamNode[] nodes, RepositoryManager manager, IProgressMonitor monitor) throws TeamException { - manager.update(getIResourcesFrom(nodes), Command.NO_LOCAL_OPTIONS, false, monitor); - } - - protected void runUpdateIgnoreLocalShallow(ITeamNode[] nodes, RepositoryManager manager, IProgressMonitor monitor) throws TeamException { - manager.update(getIResourcesFrom(nodes), new Command.LocalOption[] { Update.IGNORE_LOCAL_CHANGES, Command.DO_NOT_RECURSE }, false, monitor); - } - - protected void runUpdateShallow(ITeamNode[] nodes, RepositoryManager manager, IProgressMonitor monitor) throws TeamException { - manager.update(getIResourcesFrom(nodes), new Command.LocalOption[] { Command.DO_NOT_RECURSE }, false, monitor); - } - - protected IResource[] getIResourcesFrom(ITeamNode[] nodes) { - List resources = new ArrayList(nodes.length); - for (int i = 0; i < nodes.length; i++) { - resources.add(nodes[i].getResource()); - } - return (IResource[]) resources.toArray(new IResource[resources.size()]); - } - - protected boolean isEnabled(ITeamNode node) { - // The update action is enabled only for non-conflicting incoming changes - return new SyncSet(new StructuredSelection(node)).hasIncomingChanges(); - } - - /** - * Prompt for mergeable conflicts. - * Note: This method is designed to be overridden by test cases. - * @return 0 to cancel, 1 to only update mergeable conflicts, 2 to overwrite if unmergeable - */ - protected int promptForMergeableConflicts() { - final boolean doAutomerge[] = new boolean[] {false}; - final int[] result = new int[] {Dialog.CANCEL}; - final Shell shell = getShell(); - shell.getDisplay().syncExec(new Runnable() { - public void run() { - ConfirmDialog dialog = new ConfirmDialog(shell); - result[0] = dialog.open(); - doAutomerge[0] = dialog.getAutomerge(); - } - }); - if (result[0] == Dialog.CANCEL) return 0; - return doAutomerge[0] ? 1 : 2; - } - - /** - * Prompt for non-automergeable conflicts. - * Note: This method is designed to be overridden by test cases. - * @return false to cancel, true to overwrite local changes - */ - protected boolean promptForConflicts() { - final boolean[] result = new boolean[] { false }; - final Shell shell = getShell(); - shell.getDisplay().syncExec(new Runnable() { - public void run() { - result[0] = MessageDialog.openQuestion(shell, Policy.bind("UpdateSyncAction.Overwrite_local_changes__5"), Policy.bind("UpdateSyncAction.You_have_local_changes_you_are_about_to_overwrite._Do_you_wish_to_continue__6")); //$NON-NLS-1$ //$NON-NLS-2$ - } - }); - return result[0]; - } - protected void removeNonApplicableNodes(SyncSet set, int syncMode) { - set.removeConflictingNodes(); - set.removeOutgoingNodes(); - } - /** - * @see MergeAction#getHelpContextID() - */ - protected String getHelpContextID() { - return IHelpContextIds.SYNC_UPDATE_ACTION; - } - - protected String getErrorTitle() { - return Policy.bind("UpdateAction.update"); //$NON-NLS-1$ - } -} |