Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolderTreeBuilder.java')
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolderTreeBuilder.java718
1 files changed, 0 insertions, 718 deletions
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolderTreeBuilder.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolderTreeBuilder.java
deleted file mode 100644
index d758cba0e..000000000
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFolderTreeBuilder.java
+++ /dev/null
@@ -1,718 +0,0 @@
-package org.eclipse.team.internal.ccvs.core.resources;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2002.
- * All Rights Reserved.
- */
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.MultiStatus;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.team.internal.ccvs.core.CVSException;
-import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
-import org.eclipse.team.internal.ccvs.core.CVSStatus;
-import org.eclipse.team.internal.ccvs.core.CVSTag;
-import org.eclipse.team.internal.ccvs.core.ICVSFile;
-import org.eclipse.team.internal.ccvs.core.ICVSFolder;
-import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource;
-import org.eclipse.team.internal.ccvs.core.ICVSResource;
-import org.eclipse.team.internal.ccvs.core.Policy;
-import org.eclipse.team.internal.ccvs.core.client.Command;
-import org.eclipse.team.internal.ccvs.core.client.Session;
-import org.eclipse.team.internal.ccvs.core.client.Update;
-import org.eclipse.team.internal.ccvs.core.client.Command.GlobalOption;
-import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption;
-import org.eclipse.team.internal.ccvs.core.client.Command.QuietOption;
-import org.eclipse.team.internal.ccvs.core.client.listeners.IStatusListener;
-import org.eclipse.team.internal.ccvs.core.client.listeners.IUpdateMessageListener;
-import org.eclipse.team.internal.ccvs.core.client.listeners.StatusListener;
-import org.eclipse.team.internal.ccvs.core.client.listeners.UpdateListener;
-import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation;
-import org.eclipse.team.internal.ccvs.core.connection.CVSServerException;
-import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
-import org.eclipse.team.internal.ccvs.core.syncinfo.MutableResourceSyncInfo;
-import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
-
-/*
- * This class is responsible for building a remote tree that shows the repository
- * state of a locally loaded folder tree.
- *
- * It is used as follows
- *
- * RemoteFolderTreeBuilder.buildRemoteTree(CVSRepositoryLocation, IManagedFolder, String, IProgressMonitor);
- *
- * The provider IManagedFolder can be a local resource or a RemoteFolderTree that
- * that was previously built.
- */
-public class RemoteFolderTreeBuilder {
-
- private static final int MAX_REVISION_FETCHES_PER_CONNECTION = 1024;
-
- private Map fileDeltas;
- private List changedFiles;
- private Map remoteFolderTable;
-
- private ICVSFolder root;
- private RemoteFolderTree remoteRoot;
- private CVSRepositoryLocation repository;
-
- private CVSTag tag;
-
- private LocalOption[] updateLocalOptions;
-
- private boolean projectDoesNotExist = false;
-
- private static String UNKNOWN = ""; //$NON-NLS-1$
- private static String DELETED = "DELETED"; //$NON-NLS-1$
- private static String ADDED = "ADDED"; //$NON-NLS-1$
- private static String FOLDER = "FOLDER"; //$NON-NLS-1$
-
- private static Map EMPTY_MAP = new HashMap();
-
- static class DeltaNode {
- int syncState = Update.STATE_NONE;
- String name;
- String revision;
-
- DeltaNode(String name, String revision, int syncState) {
- this.name = name;
- this.revision = revision;
- this.syncState = syncState;
- }
-
- String getName() {
- return name;
- }
-
- String getRevision() {
- return revision;
- }
-
- int getSyncState() {
- return syncState;
- }
- }
-
-
- private RemoteFolderTreeBuilder(CVSRepositoryLocation repository, ICVSFolder root, CVSTag tag) {
- this.repository = repository;
- this.root = root;
- this.tag = tag;
- this.fileDeltas = new HashMap();
- this.changedFiles = new ArrayList();
- this.remoteFolderTable = new HashMap();
-
- // Build the local options
- List localOptions = new ArrayList();
- localOptions.add(Update.RETRIEVE_ABSENT_DIRECTORIES);
- if (tag != null) {
- if (tag.getType() == CVSTag.HEAD) {
- localOptions.add(Update.CLEAR_STICKY);
- } else {
- localOptions.add(Update.makeTagOption(tag));
- }
- }
- updateLocalOptions = (LocalOption[])localOptions.toArray(new LocalOption[localOptions.size()]);
- }
-
- private LocalOption[] getOptionsWithoutTag() {
- // Build the local options
- List localOptions = new ArrayList();
- localOptions.add(Update.RETRIEVE_ABSENT_DIRECTORIES);
- return (LocalOption[])localOptions.toArray(new LocalOption[localOptions.size()]);
- }
-
- public static RemoteFolderTree buildBaseTree(CVSRepositoryLocation repository, ICVSFolder root, CVSTag tag, IProgressMonitor progress) throws CVSException {
- try {
- RemoteFolderTreeBuilder builder = new RemoteFolderTreeBuilder(repository, root, tag);
- progress.beginTask(null, 100);
- IProgressMonitor subProgress = Policy.infiniteSubMonitorFor(progress, 100);
- subProgress.beginTask(null, 512); //$NON-NLS-1$
- subProgress.subTask(Policy.bind("RemoteFolderTreeBuilder.buildingBase", root.getName())); //$NON-NLS-1$
- return builder.buildBaseTree(null, root, subProgress);
- } finally {
- progress.done();
- }
- }
-
- public static RemoteFolderTree buildRemoteTree(CVSRepositoryLocation repository, IContainer root, CVSTag tag, IProgressMonitor monitor) throws CVSException {
- return buildRemoteTree(repository, CVSWorkspaceRoot.getCVSFolderFor(root), tag, monitor);
- }
-
- public static RemoteFolderTree buildRemoteTree(CVSRepositoryLocation repository, ICVSFolder root, CVSTag tag, IProgressMonitor monitor) throws CVSException {
- RemoteFolderTreeBuilder builder = new RemoteFolderTreeBuilder(repository, root, tag);
- return builder.buildTree(monitor);
- }
-
- public static RemoteFile buildRemoteTree(CVSRepositoryLocation repository, ICVSFile file, CVSTag tag, IProgressMonitor monitor) throws CVSException {
- RemoteFolderTreeBuilder builder = new RemoteFolderTreeBuilder(repository, file.getParent(), tag);
- return builder.buildTree(file, monitor);
- }
-
- private RemoteFolderTree buildTree(IProgressMonitor monitor) throws CVSException {
-
- // Make sure that the cvs commands are not quiet during this operations
- QuietOption quietness = CVSProviderPlugin.getPlugin().getQuietness();
- try {
- CVSProviderPlugin.getPlugin().setQuietness(Command.VERBOSE);
-
- monitor.beginTask(null, 100);
-
- Policy.checkCanceled(monitor);
- Session session = new Session(repository, root, false);
- session.open(Policy.subMonitorFor(monitor, 10));
- try {
- Policy.checkCanceled(monitor);
- fetchDelta(session, Session.CURRENT_LOCAL_FOLDER, Policy.subMonitorFor(monitor, 50));
- if (projectDoesNotExist) {
- // We cannot handle the case where a project (i.e. the top-most CVS folder)
- // has been deleted directly on the sever (i.e. deleted using rm -rf)
- if (root.isCVSFolder() && ! root.isManaged()) {
- throw new CVSException(Policy.bind("RemoteFolderTreeBuild.folderDeletedFromServer", root.getFolderSyncInfo().getRepository())); //$NON-NLS-1$
- } else {
- return null;
- }
- }
- } finally {
- session.close();
- }
- // We need a second session because of the use of a different handle on the same remote resource
- // Perhaps we could support the changing of a sessions root as long as
- // the folder sync info is the same
- remoteRoot =
- new RemoteFolderTree(null, root.getName(), repository,
- new Path(root.getFolderSyncInfo().getRepository()),
- tagForRemoteFolder(root, tag));
- session = new Session(repository, remoteRoot, false);
- session.open(Policy.subMonitorFor(monitor, 10));
- try {
- // Set up an infinite progress monitor for the recursive build
- IProgressMonitor subProgress = Policy.infiniteSubMonitorFor(monitor, 30);
- subProgress.beginTask(null, 512);
- // Build the remote tree
- buildRemoteTree(session, root, remoteRoot, Path.EMPTY, subProgress);
- // we can only fecth the status for up to 1024 files in a single connection due to
- // the server which has a limit on the number of "open" files.
- if (!changedFiles.isEmpty() && changedFiles.size() <= MAX_REVISION_FETCHES_PER_CONNECTION) {
- fetchFileRevisions(session, (String[])changedFiles.toArray(new String[changedFiles.size()]), Policy.subMonitorFor(monitor, 20));
- }
- } finally {
- session.close();
- }
-
- // If there were more than 1024 changed files, we need a connection per each 1024
- if (!changedFiles.isEmpty() && changedFiles.size() > MAX_REVISION_FETCHES_PER_CONNECTION) {
- String[] allChangedFiles = (String[])changedFiles.toArray(new String[changedFiles.size()]);
- int iterations = (allChangedFiles.length / MAX_REVISION_FETCHES_PER_CONNECTION)
- + (allChangedFiles.length % MAX_REVISION_FETCHES_PER_CONNECTION == 0 ? 0 : 1);
- for (int i = 0; i < iterations ; i++) {
- int length = Math.min(MAX_REVISION_FETCHES_PER_CONNECTION,
- allChangedFiles.length - (MAX_REVISION_FETCHES_PER_CONNECTION * i));
- String buffer[] = new String[length];
- System.arraycopy(allChangedFiles, i * MAX_REVISION_FETCHES_PER_CONNECTION, buffer, 0, length);
- session = new Session(repository, remoteRoot, false);
- session.open(Policy.subMonitorFor(monitor, 1));
- try {
- fetchFileRevisions(session, buffer, Policy.subMonitorFor(monitor, 2));
- } finally {
- session.close();
- }
- }
- }
-
- return remoteRoot;
-
- } finally {
- CVSProviderPlugin.getPlugin().setQuietness(quietness);
- monitor.done();
- }
- }
-
- private RemoteFile buildTree(ICVSFile file, IProgressMonitor monitor) throws CVSException {
- QuietOption quietness = CVSProviderPlugin.getPlugin().getQuietness();
- try {
- CVSProviderPlugin.getPlugin().setQuietness(Command.VERBOSE);
-
- monitor.beginTask(null, 100);
-
- // Query the server to see if there is a delta available
- Policy.checkCanceled(monitor);
- Session session = new Session(repository, root, false);
- session.open(Policy.subMonitorFor(monitor, 10));
- try {
- Policy.checkCanceled(monitor);
- fetchDelta(session, file.getName(), Policy.subMonitorFor(monitor, 50));
- if (projectDoesNotExist) {
- return null;
- }
- } finally {
- session.close();
- }
- // Create a parent for the remote resource
- remoteRoot =
- new RemoteFolderTree(null, root.getName(), repository,
- new Path(root.getFolderSyncInfo().getRepository()),
- tagForRemoteFolder(root, tag));
- // Create the remote resource (using the delta if there is one)
- RemoteFile remoteFile;
- Map deltas = (Map)fileDeltas.get(Path.EMPTY);
- if (deltas == null || deltas.isEmpty()) {
- // If the file is an addition, return null as the remote
- // Note: If there was a conflicting addition, the delta would not be empty
- if ( ! file.isManaged() || file.getSyncInfo().isAdded()) {
- return null;
- }
- remoteFile = new RemoteFile(remoteRoot, file.getSyncInfo());
- } else {
- DeltaNode d = (DeltaNode)deltas.get(file.getName());
- if (d.getRevision() == DELETED) {
- return null;
- }
- remoteFile = new RemoteFile(remoteRoot, d.getSyncState(), file.getName(), tagForRemoteFolder(remoteRoot, tag));
- }
- // Add the resource to its parent
- remoteRoot.setChildren(new ICVSRemoteResource[] {remoteFile});
- // If there was a delta, ftech the new revision
- if (!changedFiles.isEmpty()) {
- // Add the remote folder to the remote folder lookup table (used to update file revisions)
- remoteFolderTable.put(new Path(remoteRoot.getFolderSyncInfo().getRemoteLocation()), remoteRoot);
- session = new Session(repository, remoteRoot, false);
- session.open(Policy.subMonitorFor(monitor, 10));
- try {
- fetchFileRevisions(session, (String[])changedFiles.toArray(new String[changedFiles.size()]), Policy.subMonitorFor(monitor, 20));
- } finally {
- session.close();
- }
- }
- return remoteFile;
-
- } finally {
- CVSProviderPlugin.getPlugin().setQuietness(quietness);
- monitor.done();
- }
- }
-
- /*
- * Build the base remote tree from the local tree.
- *
- * The localPath is used to retrieve deltas from the recorded deltas
- *
- * Does 1 work for each managed file and folder
- */
- private RemoteFolderTree buildBaseTree(RemoteFolderTree parent, ICVSFolder local, IProgressMonitor monitor) throws CVSException {
-
- Policy.checkCanceled(monitor);
-
- // Create a remote folder tree corresponding to the local resource
- RemoteFolderTree remote = new RemoteFolderTree(parent, local.getName(), repository, new Path(local.getFolderSyncInfo().getRepository()), local.getFolderSyncInfo().getTag());
-
- // Create a List to contain the created children
- List children = new ArrayList();
-
- // Build the child folders corresponding to local folders base
- ICVSResource[] folders = local.members(ICVSFolder.FOLDER_MEMBERS);
- for (int i=0;i<folders.length;i++) {
- ICVSFolder folder = (ICVSFolder)folders[i];
- if (folder.isManaged() && folder.isCVSFolder()) {
- monitor.worked(1);
- children.add(buildBaseTree(remote, folder, monitor));
- }
- }
-
- // Build the child files corresponding to local files base
- ICVSResource[] files = local.members(ICVSFolder.FILE_MEMBERS);
- for (int i=0;i<files.length;i++) {
- ICVSFile file = (ICVSFile)files[i];
- ResourceSyncInfo info = file.getSyncInfo();
- // if there is no sync info then there is no base
- if (info==null)
- continue;
- // There is no remote if the file was added
- if (info.isAdded())
- continue;
- // If the file was deleted locally, we need to generate a new sync info without the delete flag
- if (info.isDeleted()) {
- MutableResourceSyncInfo undeletedInfo = info.cloneMutable();
- undeletedInfo.setDeleted(false);
- info = undeletedInfo;
- }
- children.add(new RemoteFile(remote, info));
- monitor.worked(1);
- }
-
- // Add the children to the remote folder tree
- remote.setChildren((ICVSRemoteResource[])children.toArray(new ICVSRemoteResource[children.size()]));
-
- return remote;
- }
-
- /*
- * Build the remote tree from the local tree and the recorded deltas.
- *
- * The localPath is used to retrieve deltas from the recorded deltas
- *
- * Does 1 work for each file and folder delta processed
- */
- private void buildRemoteTree(Session session, ICVSFolder local, RemoteFolderTree remote, IPath localPath, IProgressMonitor monitor) throws CVSException {
-
- Policy.checkCanceled(monitor);
-
- // Add the remote folder to the remote folder lookup table (used to update file revisions)
- remoteFolderTable.put(new Path(remote.getFolderSyncInfo().getRemoteLocation()), remote);
-
- // Create a map to contain the created children
- Map children = new HashMap();
-
- // If there's no corresponding local resource then we need to fetch its contents in order to populate the deltas
- if (local == null) {
- fetchNewDirectory(session, remote, localPath, monitor);
- }
-
- // Fetch the delta's for the folder
- Map deltas = (Map)fileDeltas.get(localPath);
- if (deltas == null)
- deltas = EMPTY_MAP;
-
- // If there is a local, use the local children to start buidling the remote children
- if (local != null) {
- // Build the child folders corresponding to local folders
- ICVSResource[] folders = local.members(ICVSFolder.FOLDER_MEMBERS);
- for (int i=0;i<folders.length;i++) {
- ICVSFolder folder = (ICVSFolder)folders[i];
- DeltaNode d = (DeltaNode)deltas.get(folder.getName());
- if (folder.isCVSFolder() && ! isOrphanedSubtree(session, folder) && (d==null || d.getRevision() != DELETED)) {
- children.put(folders[i].getName(),
- new RemoteFolderTree(remote, folders[i].getName(), repository,
- new Path(folder.getFolderSyncInfo().getRepository()),
- tagForRemoteFolder(folder,tag)));
- }
- }
- // Build the child files corresponding to local files
- ICVSResource[] files = local.members(ICVSFolder.FILE_MEMBERS);
- for (int i=0;i<files.length;i++) {
- ICVSFile file = (ICVSFile)files[i];
-
- DeltaNode d = (DeltaNode)deltas.get(file.getName());
- ResourceSyncInfo info = file.getSyncInfo();
- // if there is no sync info then there isn't a remote file for this local file on the
- // server.
- if (info==null)
- continue;
- // There is no remote if the file was added and we didn't get a conflict (C) indicator from the server
- if (info.isAdded() && d==null)
- continue;
- // There is no remote if the file was deleted and we didn;t get a remove (R) indicator from the server
- if (info.isDeleted() && d==null)
- continue;
-
- int type = d==null ? Update.STATE_NONE : d.getSyncState();
- children.put(file.getName(), new RemoteFile(remote, type, info));
- }
- }
-
- // Build the children for new or out-of-date resources from the deltas
- Iterator i = deltas.keySet().iterator();
- while (i.hasNext()) {
- String name = (String)i.next();
- DeltaNode d = (DeltaNode)deltas.get(name);
- String revision = d.getRevision();
- if (revision == FOLDER) {
- // XXX should getRemotePath() return an IPath instead of a String?
- children.put(name, new RemoteFolderTree(remote, repository,
- new Path(remote.getRepositoryRelativePath()).append(name),
- tagForRemoteFolder(remote, tag)));
- } else if (revision == ADDED) {
- children.put(name, new RemoteFile(remote, d.getSyncState(), name, tagForRemoteFolder(remote, tag)));
- } else if (revision == UNKNOWN) {
- // The local resource is out of sync with the remote.
- // Create a RemoteFile associated with the tag so we are assured of getting the proper revision
- // (Note: this will replace the RemoteFile added from the local base)
- children.put(name, new RemoteFile(remote, d.getSyncState(), name, tagForRemoteFolder(remote, tag)));
- } else if (revision == DELETED) {
- // This should have been deleted while creating from the local resources.
- // If it wasn't, delete it now.
- if (children.containsKey(name))
- children.remove(name);
- } else {
- // We should never get here
- }
- monitor.worked(1);
- }
-
- // Add the children to the remote folder tree
- remote.setChildren((ICVSRemoteResource[])children.values().toArray(new ICVSRemoteResource[children.size()]));
-
- // We have to delay building the child folders to support the proper fetching of new directories
- // due to the fact that the same CVS home directory (i.e. the same root directory) must
- // be used for all requests sent over the same connection
- Iterator childIterator = children.entrySet().iterator();
- List emptyChildren = new ArrayList();
- while (childIterator.hasNext()) {
- Map.Entry entry = (Map.Entry)childIterator.next();
- if (((RemoteResource)entry.getValue()).isFolder()) {
- RemoteFolderTree remoteFolder = (RemoteFolderTree)entry.getValue();
- String name = (String)entry.getKey();
- ICVSFolder localFolder;
- DeltaNode d = (DeltaNode)deltas.get(name);
- // for directories that are new on the server
- if (d!=null && d.getRevision() == FOLDER)
- localFolder = null;
- else
- localFolder = local.getFolder(name);
- buildRemoteTree(session, localFolder, remoteFolder, localPath.append(name), monitor);
- // Record any children that are empty
- if (pruneEmptyDirectories() && remoteFolder.getChildren().length == 0) {
- // Prune if the local folder is also empty.
- if (localFolder == null || (localFolder.members(ICVSFolder.ALL_MEMBERS).length == 0))
- emptyChildren.add(remoteFolder);
- else {
- // Also prune if the tag we are fetching is not HEAD and differs from the tag of the local folder
- FolderSyncInfo info = localFolder.getFolderSyncInfo();
- if (tag != null && info != null && ! tag.equals(CVSTag.DEFAULT) && ! tag.equals(info.getTag()))
- emptyChildren.add(remoteFolder);
- }
- }
- }
- }
-
- // Prune any empty child folders
- if (pruneEmptyDirectories() && !emptyChildren.isEmpty()) {
- List newChildren = new ArrayList();
- newChildren.addAll(Arrays.asList(remote.getChildren()));
- newChildren.removeAll(emptyChildren);
- remote.setChildren((ICVSRemoteResource[])newChildren.toArray(new ICVSRemoteResource[newChildren.size()]));
-
- }
- }
-
- /*
- * This method fetches the delta between the local state and the remote state of the resource tree
- * and records the deltas in the fileDeltas instance variable
- *
- * Returns the list of changed files
- */
- private List fetchDelta(Session session, String argument, final IProgressMonitor monitor) throws CVSException {
-
- // Create an listener that will accumulate new and removed files and folders
- final List newChildDirectories = new ArrayList();
- IUpdateMessageListener listener = new IUpdateMessageListener() {
- public void directoryInformation(ICVSFolder root, IPath path, boolean newDirectory) {
- if (newDirectory) {
- // Record new directory with parent so it can be retrieved when building the parent
- recordDelta(path, FOLDER, Update.STATE_NONE);
- monitor.subTask(Policy.bind("RemoteFolderTreeBuilder.receivingDelta", path.toString())); //$NON-NLS-1$
- // Record new directory to be used as a parameter to fetch its contents
- newChildDirectories.add(path.toString());
- }
- }
- public void directoryDoesNotExist(ICVSFolder root, IPath path) {
- // Record removed directory with parent so it can be removed when building the parent
- if (path.isEmpty()) {
- projectDoesNotExist = true;
- } else {
- recordDelta(path, DELETED, Update.STATE_NONE);
- monitor.subTask(Policy.bind("RemoteFolderTreeBuilder.receivingDelta", path.toString())); //$NON-NLS-1$
- }
- }
- public void fileInformation(int type, ICVSFolder root, String filename) {
- // Cases that do not require action are:
- // case 'A' : = A locally added file that does not exists remotely
- // case '?' : = A local file that has not been added and does not exists remotely
- // case 'M' : = A locally modified file that has not been modified remotely
- switch(type) {
- case Update.STATE_MERGEABLE_CONFLICT :
- case Update.STATE_CONFLICT :
- // We have an remote change to a modified local file
- // The change could be a local change conflicting with a remote deletion.
- // If so, the deltas may already have a DELETED for the file.
- // We shouldn't override this DELETED
- IPath filePath = new Path(filename);
- Map deltas = deltas = (Map)fileDeltas.get(filePath.removeLastSegments(1));
- DeltaNode d = deltas != null ? (DeltaNode)deltas.get(filePath.lastSegment()) : null;
- if ((d!=null) && (d.getRevision() == DELETED))
- break;
- case Update.STATE_DELETED : // We have a locally removed file that still exists remotely
- case Update.STATE_REMOTE_CHANGES : // We have an remote change to an unmodified local file
- changedFiles.add(filename);
- recordDelta(new Path(filename), UNKNOWN, type);
- monitor.subTask(Policy.bind("RemoteFolderTreeBuilder.receivingDelta", filename)); //$NON-NLS-1$
- break;
- }
- }
- public void fileDoesNotExist(ICVSFolder root, String filename) {
- recordDelta(new Path(filename), DELETED, Update.STATE_NONE);
- monitor.subTask(Policy.bind("RemoteFolderTreeBuilder.receivingDelta", filename)); //$NON-NLS-1$
- }
- };
-
- // Perform a "cvs -n update -d [-r tag] ." in order to get the
- // messages from the server that will indicate what has changed on the
- // server.
- IStatus status = Command.UPDATE.execute(session,
- new GlobalOption[] { Command.DO_NOT_CHANGE },
- updateLocalOptions,
- new String[] { argument },
- new UpdateListener(listener),
- monitor);
- return changedFiles;
- }
- /*
- * Fetch the children of a previously unknown directory.
- *
- * The fetch may do up to 2 units of work in the provided monitor.
- */
- private void fetchNewDirectory(Session session, RemoteFolderTree newFolder, IPath localPath, final IProgressMonitor monitor) throws CVSException {
-
- // Create an listener that will accumulate new files and folders
- IUpdateMessageListener listener = new IUpdateMessageListener() {
- public void directoryInformation(ICVSFolder root, IPath path, boolean newDirectory) {
- if (newDirectory) {
- // Record new directory with parent so it can be retrieved when building the parent
- // NOTE: Check path prefix
- recordDelta(path, FOLDER, Update.STATE_NONE);
- monitor.subTask(Policy.bind("RemoteFolderTreeBuilder.receivingDelta", path.toString())); //$NON-NLS-1$
- }
- }
- public void directoryDoesNotExist(ICVSFolder root, IPath path) {
- }
- public void fileInformation(int type, ICVSFolder root, String filename) {
- // NOTE: Check path prefix
- changedFiles.add(filename);
- recordDelta(new Path(filename), ADDED, type);
- monitor.subTask(Policy.bind("RemoteFolderTreeBuilder.receivingDelta", filename)); //$NON-NLS-1$
- }
- public void fileDoesNotExist(ICVSFolder root, String filename) {
- }
- };
-
- // NOTE: Should use the path relative to the remoteRoot
- IPath path = new Path(newFolder.getRepositoryRelativePath());
- IStatus status = Command.UPDATE.execute(session,
- new GlobalOption[] { Command.DO_NOT_CHANGE },
- updateLocalOptions,
- new String[] { localPath.toString() },
- new UpdateListener(listener),
- Policy.subMonitorFor(monitor, 1));
- if (status.getCode() == CVSStatus.SERVER_ERROR) {
- // FIXME: This should be refactored (maybe static methods on CVSException?)
- CVSServerException e = new CVSServerException(status);
- if ( ! e.isNoTagException() && e.containsErrors())
- throw e;
- // we now know that this is an exception caused by a cvs bug.
- // if the folder has no files in it (just subfolders) cvs does not respond with the subfolders...
- // workaround: retry the request with no tag to get the directory names (if any)
- Policy.checkCanceled(monitor);
- status = Command.UPDATE.execute(session,
- new GlobalOption[] { Command.DO_NOT_CHANGE },
- getOptionsWithoutTag(),
- new String[] { localPath.toString() },
- new UpdateListener(listener),
- Policy.subMonitorFor(monitor, 1));
- if (status.getCode() == CVSStatus.SERVER_ERROR) {
- throw new CVSServerException(status);
- }
- }
- }
-
- // Get the file revisions for the given filenames
- private void fetchFileRevisions(Session session, String[] fileNames, final IProgressMonitor monitor) throws CVSException {
-
- // Create a listener for receiving the revision info
- final Map revisions = new HashMap();
- final List exceptions = new ArrayList();
- IStatusListener listener = new IStatusListener() {
- public void fileStatus(ICVSFolder root, IPath path, String remoteRevision) {
- try {
- updateRevision(path, remoteRevision);
- monitor.subTask(Policy.bind("RemoteFolderTreeBuilder.receivingRevision", path.toString())); //$NON-NLS-1$
- } catch (CVSException e) {
- exceptions.add(e);
- }
- }
- };
-
- // Perform a "cvs status..." with a custom message handler
- IStatus status = Command.STATUS.execute(session,
- Command.NO_GLOBAL_OPTIONS,
- Command.NO_LOCAL_OPTIONS,
- fileNames,
- new StatusListener(listener),
- monitor);
- if (status.getCode() == CVSStatus.SERVER_ERROR) {
- throw new CVSServerException(status);
- }
-
- // Report any exceptions that occured fecthing the revisions
- if ( ! exceptions.isEmpty()) {
- if (exceptions.size() == 1) {
- throw (CVSException)exceptions.get(0);
- } else {
- MultiStatus multi = new MultiStatus(CVSProviderPlugin.ID, 0, Policy.bind("RemoteFolder.errorFetchingRevisions"), null); //$NON-NLS-1$
- for (int i = 0; i < exceptions.size(); i++) {
- multi.merge(((CVSException)exceptions.get(i)).getStatus());
- }
- throw new CVSException(multi);
- }
- }
- }
-
- private boolean pruneEmptyDirectories() {
- return CVSProviderPlugin.getPlugin().getPruneEmptyDirectories();
- }
- /*
- * Record the deltas in a double map where the outer key is the parent directory
- * and the inner key is the file name. The value is the revision of the file or
- * DELETED (file or folder). New folders have a revision of FOLDER.
- *
- * A revison of UNKNOWN indicates that the revision has not been fetched
- * from the repository yet.
- */
- private void recordDelta(IPath path, String revision, int syncState) {
- IPath parent = path.removeLastSegments(1);
- Map deltas = (Map)fileDeltas.get(parent);
- if (deltas == null) {
- deltas = new HashMap();
- fileDeltas.put(parent, deltas);
- }
- String name = path.lastSegment();
- deltas.put(name, new DeltaNode(name, revision, syncState));
- }
-
- private void updateRevision(IPath path, String revision) throws CVSException {
- RemoteFolderTree folder = (RemoteFolderTree)remoteFolderTable.get(path.removeLastSegments(1));
- if (folder == null) {
- throw new CVSException(Policy.bind("RemoteFolderTreeBuilder.missingParent", path.toString(), revision));//$NON-NLS-1$
- }
- ((RemoteFile)folder.getFile(path.lastSegment())).setRevision(revision);
- }
-
- /*
- * Return the tag that should be associated with a remote folder.
- *
- * This method is used to ensure that new directories contain the tag
- * derived from the parant local folder when appropriate. For instance,
- *
- * The tag should be the provided tag. However, if tag is null, the
- * tag for the folder should be derived from the provided reference folder
- * which could be the local resource corresponding to the remote or the parent
- * of the remote.
- */
- private CVSTag tagForRemoteFolder(ICVSFolder folder, CVSTag tag) throws CVSException {
- return tag == null ? folder.getFolderSyncInfo().getTag() : tag;
- }
-
- private boolean isOrphanedSubtree(Session session, ICVSFolder mFolder) throws CVSException {
- return mFolder.isCVSFolder() && ! mFolder.isManaged() && ! mFolder.equals(session.getLocalRoot()) && mFolder.getParent().isCVSFolder();
- }
-}
-

Back to the top