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/CVSTeamProvider.java')
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java1147
1 files changed, 0 insertions, 1147 deletions
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java
deleted file mode 100644
index 45408076a..000000000
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTeamProvider.java
+++ /dev/null
@@ -1,1147 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2002 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
- *
- * Contributors:
- * IBM - Initial API and implementation
- ******************************************************************************/
-package org.eclipse.team.internal.ccvs.core;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceVisitor;
-import org.eclipse.core.resources.team.IMoveDeleteHook;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.team.core.RepositoryProvider;
-import org.eclipse.team.core.Team;
-import org.eclipse.team.core.TeamException;
-import org.eclipse.team.core.sync.IRemoteSyncElement;
-import org.eclipse.team.internal.ccvs.core.client.Command;
-import org.eclipse.team.internal.ccvs.core.client.Commit;
-import org.eclipse.team.internal.ccvs.core.client.Session;
-import org.eclipse.team.internal.ccvs.core.client.Tag;
-import org.eclipse.team.internal.ccvs.core.client.Update;
-import org.eclipse.team.internal.ccvs.core.client.Command.KSubstOption;
-import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption;
-import org.eclipse.team.internal.ccvs.core.client.listeners.AdminKSubstListener;
-import org.eclipse.team.internal.ccvs.core.client.listeners.DiffListener;
-import org.eclipse.team.internal.ccvs.core.client.listeners.ICommandOutputListener;
-import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation;
-import org.eclipse.team.internal.ccvs.core.connection.CVSServerException;
-import org.eclipse.team.internal.ccvs.core.resources.CVSRemoteSyncElement;
-import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
-import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer;
-import org.eclipse.team.internal.ccvs.core.streams.CRLFtoLFInputStream;
-import org.eclipse.team.internal.ccvs.core.streams.LFtoCRLFInputStream;
-import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
-import org.eclipse.team.internal.ccvs.core.syncinfo.MutableResourceSyncInfo;
-import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
-import org.eclipse.team.internal.ccvs.core.util.Assert;
-import org.eclipse.team.internal.ccvs.core.util.PrepareForReplaceVisitor;
-import org.eclipse.team.internal.ccvs.core.util.ReplaceWithBaseVisitor;
-
-/**
- * This class acts as both the ITeamNature and the ITeamProvider instances
- * required by the Team core.
- *
- * The current stat of this class and it's plugin is EXPERIMENTAL.
- * As such, it is subject to change except in it's conformance to the
- * TEAM API which it implements.
- *
- * Questions:
- *
- * How should a project/reource rename/move effect the provider?
- *
- * Currently we always update with -P. Is this OK?
- * - A way to allow customizable options would be nice
- *
- * Is the -l option valid for commit and does it work properly for update and commit?
- *
- * Do we need an IUserInteractionProvider in the CVS core
- * - prompt for user info (caching could be separate)
- * - get release comments
- * - prompt for overwrite of unmanaged files
- *
- * Need a mechanism for communicating meta-information (provided by Team?)
- *
- * Should pass null when there are no options for a cvs command
- *
- * We currently write the files to disk and do a refreshLocal to
- * have them appear in Eclipse. This may be changed in the future.
- */
-public class CVSTeamProvider extends RepositoryProvider {
- private static final boolean IS_CRLF_PLATFORM = Arrays.equals(
- System.getProperty("line.separator").getBytes(), new byte[] { '\r', '\n' }); //$NON-NLS-1$
-
- private CVSWorkspaceRoot workspaceRoot;
- private IProject project;
- private String comment = ""; //$NON-NLS-1$
-
- private static IMoveDeleteHook moveDeleteHook;
-
- /**
- * No-arg Constructor for IProjectNature conformance
- */
- public CVSTeamProvider() {
- }
-
-
-
- /**
- * @see IProjectNature#deconfigure()
- */
- public void deconfigure() throws CoreException {
- // when a nature is removed from the project, notify the synchronizer that
- // we no longer need the sync info cached. This does not affect the actual CVS
- // meta directories on disk, and will remain unless a client calls unmanage().
- try {
- EclipseSynchronizer.getInstance().flush(getProject(), true, true /*flush deep*/, null);
- } catch(CVSException e) {
- throw new CoreException(e.getStatus());
- } finally {
- CVSProviderPlugin.broadcastProjectDeconfigured(getProject());
- }
- }
-
- /**
- * @see IProjectNature#getProject()
- */
- public IProject getProject() {
- return project;
- }
-
-
-
- /**
- * @see IProjectNature#setProject(IProject)
- */
- public void setProject(IProject project) {
- this.project = project;
- try {
- this.workspaceRoot = new CVSWorkspaceRoot(project);
- // Ensure that the project has CVS info
- if (workspaceRoot.getLocalRoot().getFolderSyncInfo() == null) {
- throw new CVSException(new CVSStatus(CVSStatus.ERROR, Policy.bind("CVSTeamProvider.noFolderInfo", project.getName()))); //$NON-NLS-1$
- }
- } catch (CVSException e) {
- // Log any problems creating the CVS managed resource
- CVSProviderPlugin.log(e);
- }
- }
-
-
-
- /**
- * Add the given resources to the project.
- * <p>
- * The sematics follow that of CVS in the sense that any folders
- * being added are created remotely as a result of this operation
- * while files are created remotely on the next commit.
- * </p>
- * <p>
- * This method uses the team file type registry to determine the type
- * of added files. If the extension of the file is not in the registry,
- * the file is assumed to be binary.
- * </p>
- * <p>
- * NOTE: for now we do three operations: one each for folders, text files and binary files.
- * We should optimize this when time permits to either use one operations or defer server
- * contact until the next commit.
- * </p>
- *
- * <p>
- * There are special semantics for adding the project itself to the repo. In this case, the project
- * must be included in the resources array.
- * </p>
- */
- public void add(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException {
-
- // Visit the children of the resources using the depth in order to
- // determine which folders, text files and binary files need to be added
- // A TreeSet is needed for the folders so they are in the right order (i.e. parents created before children)
- final SortedSet folders = new TreeSet();
- // Sets are required for the files to ensure that files will not appear twice if there parent was added as well
- // and the depth isn't zero
- final Map /* from KSubstOption to Set */ files = new HashMap();
- final TeamException[] eHolder = new TeamException[1];
- for (int i=0; i<resources.length; i++) {
-
- final IResource currentResource = resources[i];
-
- // Throw an exception if the resource is not a child of the receiver
- checkIsChild(currentResource);
-
- try {
- // Auto-add parents if they are not already managed
- IContainer parent = currentResource.getParent();
- ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(currentResource);
- while (parent.getType() != IResource.ROOT && parent.getType() != IResource.PROJECT && ! cvsResource.isManaged()) {
- folders.add(parent.getProjectRelativePath().toString());
- parent = parent.getParent();
- }
-
- // Auto-add children
- currentResource.accept(new IResourceVisitor() {
- public boolean visit(IResource resource) {
- ICVSResource mResource = CVSWorkspaceRoot.getCVSResourceFor(resource);
- // Add the resource is its not already managed and it was either
- // added explicitly (is equal currentResource) or is not ignored
- if (! mResource.isManaged() && (currentResource.equals(resource) || ! mResource.isIgnored())) {
- String name = resource.getProjectRelativePath().toString();
- if (resource.getType() == IResource.FILE) {
- KSubstOption ksubst = KSubstOption.fromFile((IFile) resource);
- Set set = (Set) files.get(ksubst);
- if (set == null) {
- set = new HashSet();
- files.put(ksubst, set);
- }
- set.add(name);
- } else {
- folders.add(name);
- }
- }
- // Always return true and let the depth determine if children are visited
- return true;
- }
- }, depth, false);
- } catch (CoreException e) {
- throw new CVSException(new Status(IStatus.ERROR, CVSProviderPlugin.ID, TeamException.UNABLE, Policy.bind("CVSTeamProvider.visitError", new Object[] {resources[i].getFullPath()}), e)); //$NON-NLS-1$
- }
- }
- // If an exception occured during the visit, throw it here
- if (eHolder[0] != null)
- throw eHolder[0];
-
- // XXX Do we need to add the project
-
- // Add the folders, followed by files!
- IStatus status;
- Session s = new Session(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot());
- progress.beginTask(null, 10 + files.size() * 10 + (folders.isEmpty() ? 0 : 10));
- try {
- // Opening the session takes 10 units of time
- s.open(Policy.subMonitorFor(progress, 10));
- if (!folders.isEmpty()) {
- status = Command.ADD.execute(s,
- Command.NO_GLOBAL_OPTIONS,
- Command.NO_LOCAL_OPTIONS,
- (String[])folders.toArray(new String[folders.size()]),
- null,
- Policy.subMonitorFor(progress, 10));
- if (status.getCode() == CVSStatus.SERVER_ERROR) {
- throw new CVSServerException(status);
- }
- }
- for (Iterator it = files.entrySet().iterator(); it.hasNext();) {
- Map.Entry entry = (Map.Entry) it.next();
- KSubstOption ksubst = (KSubstOption) entry.getKey();
- Set set = (Set) entry.getValue();
- status = Command.ADD.execute(s,
- Command.NO_GLOBAL_OPTIONS,
- new LocalOption[] { ksubst },
- (String[])set.toArray(new String[set.size()]),
- null,
- Policy.subMonitorFor(progress, 10));
- if (status.getCode() == CVSStatus.SERVER_ERROR) {
- throw new CVSServerException(status);
- }
- }
- } finally {
- s.close();
- progress.done();
- }
- }
-
- /**
- * Checkin any local changes using "cvs commit ...".
- *
- * @see ITeamProvider#checkin(IResource[], int, IProgressMonitor)
- */
- public void checkin(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException {
-
- // Build the local options
- List localOptions = new ArrayList();
- localOptions.add(Commit.makeArgumentOption(Command.MESSAGE_OPTION, comment));
-
- // If the depth is not infinite, we want the -l option
- if (depth != IResource.DEPTH_INFINITE) {
- localOptions.add(Commit.DO_NOT_RECURSE);
- }
- LocalOption[] commandOptions = (LocalOption[])localOptions.toArray(new LocalOption[localOptions.size()]);
-
- // Build the arguments list
- String[] arguments = getValidArguments(resources, commandOptions);
-
- // Commit the resources
- IStatus status;
- Session s = new Session(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot());
- progress.beginTask(null, 100);
- try {
- // Opening the session takes 20% of the time
- s.open(Policy.subMonitorFor(progress, 20));
- status = Command.COMMIT.execute(s,
- Command.NO_GLOBAL_OPTIONS,
- commandOptions,
- arguments, null,
- Policy.subMonitorFor(progress, 80));
- } finally {
- s.close();
- progress.done();
- }
- if (status.getCode() == CVSStatus.SERVER_ERROR) {
- throw new CVSServerException(status);
- }
- }
-
- /**
- * Checkout the provided resources so they can be modified locally and committed.
- *
- * Currently, we support only the optimistic model so checkout does nothing.
- *
- * @see ITeamProvider#checkout(IResource[], int, IProgressMonitor)
- */
- public void checkout(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException {
- }
-
- /**
- * @see ITeamProvider#delete(IResource[], int, IProgressMonitor)
- */
- public void delete(IResource[] resources, final IProgressMonitor progress) throws TeamException {
- try {
- progress.beginTask(null, 100);
-
- // Delete any files locally and record the names.
- // Use a resource visitor to ensure the proper depth is obtained
- final IProgressMonitor subProgress = Policy.infiniteSubMonitorFor(progress, 30);
- subProgress.beginTask(null, 256);
- final List files = new ArrayList(resources.length);
- final TeamException[] eHolder = new TeamException[1];
- for (int i=0;i<resources.length;i++) {
- IResource resource = resources[i];
- checkIsChild(resource);
- try {
- if (resource.exists()) {
- resource.accept(new IResourceVisitor() {
- public boolean visit(IResource resource) {
- try {
- ICVSResource cvsResource = workspaceRoot.getCVSResourceFor(resource);
- if (cvsResource.isManaged()) {
- String name = resource.getProjectRelativePath().toString();
- if (resource.getType() == IResource.FILE) {
- files.add(name);
- ((IFile)resource).delete(false, true, subProgress);
- }
- }
- } catch (CoreException e) {
- eHolder[0] = wrapException(e);
- // If there was a problem, don't visit the children
- return false;
- }
- // Always return true and let the depth determine if children are visited
- return true;
- }
- }, IResource.DEPTH_INFINITE, false);
- } else if (resource.getType() == IResource.FILE) {
- // If the resource doesn't exist but is a file, queue it for removal
- files.add(resource.getProjectRelativePath().toString());
- }
- } catch (CoreException e) {
- throw wrapException(e);
- }
- }
- subProgress.done();
- // If an exception occured during the visit, throw it here
- if (eHolder[0] != null) throw eHolder[0];
- // If there are no files to delete, we are done
- if (files.isEmpty()) return;
-
- // Remove the files remotely
- IStatus status;
- Session s = new Session(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot());
- s.open(progress);
- try {
- status = Command.REMOVE.execute(s,
- Command.NO_GLOBAL_OPTIONS,
- Command.NO_LOCAL_OPTIONS,
- (String[])files.toArray(new String[files.size()]),
- null,
- Policy.subMonitorFor(progress, 70));
- } finally {
- s.close();
- }
- if (status.getCode() == CVSStatus.SERVER_ERROR) {
- throw new CVSServerException(status);
- }
- } finally {
- progress.done();
- }
- }
-
- /**
- * Diff the resources against the repository and write the output to the provided
- * PrintStream in a form that is usable as a patch. The patch is rooted at the
- * project.
- */
- public void diff(IResource resource, LocalOption[] options, PrintStream stream,
- IProgressMonitor progress) throws TeamException {
-
- // Determine the command root and arguments arguments list
- ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource);
- ICVSFolder commandRoot;
- String[] arguments;
- if (cvsResource.isFolder()) {
- commandRoot = (ICVSFolder)cvsResource;
- arguments = new String[] {Session.CURRENT_LOCAL_FOLDER};
- } else {
- commandRoot = cvsResource.getParent();
- arguments = new String[] {cvsResource.getName()};
- }
-
- Session s = new Session(workspaceRoot.getRemoteLocation(), commandRoot);
- progress.beginTask(null, 100);
- try {
- s.open(Policy.subMonitorFor(progress, 20));
- Command.DIFF.execute(s,
- Command.NO_GLOBAL_OPTIONS,
- options,
- arguments,
- new DiffListener(stream),
- Policy.subMonitorFor(progress, 80));
- } finally {
- s.close();
- progress.done();
- }
- }
-
- /**
- * Replace the local version of the provided resources with the remote using "cvs update -C ..."
- *
- * @see ITeamProvider#get(IResource[], int, IProgressMonitor)
- */
- public void get(IResource[] resources, final int depth, IProgressMonitor progress) throws TeamException {
- get(resources, depth, null, progress);
- }
-
- public void get(final IResource[] resources, final int depth, CVSTag tag, IProgressMonitor progress) throws TeamException {
- try {
- progress.beginTask(null, 100);
-
- // Handle the retrival of the base in a special way
- if (tag != null && tag.equals(CVSTag.BASE)) {
- new ReplaceWithBaseVisitor().replaceWithBase(getProject(), resources, depth, Policy.subMonitorFor(progress, 100)); //$NON-NLS-1$
- return;
- }
-
- // Prepare for the replace (special handling for "cvs added" and "cvs removed" resources
- new PrepareForReplaceVisitor().visitResources(getProject(), resources, "CVSTeamProvider.scrubbingResource", depth, Policy.subMonitorFor(progress, 30)); //$NON-NLS-1$
-
- // Perform an update, ignoring any local file modifications
- List options = new ArrayList();
- options.add(Update.IGNORE_LOCAL_CHANGES);
- if(depth != IResource.DEPTH_INFINITE) {
- options.add(Command.DO_NOT_RECURSE);
- }
- LocalOption[] commandOptions = (LocalOption[]) options.toArray(new LocalOption[options.size()]);
- update(resources, commandOptions, tag, true /*createBackups*/, Policy.subMonitorFor(progress, 70));
- } finally {
- progress.done();
- }
- }
-
- /**
- * Return the remote location to which the receiver's project is mapped.
- */
- public ICVSRepositoryLocation getRemoteLocation() throws CVSException {
- try {
- return workspaceRoot.getRemoteLocation();
- } catch (CVSException e) {
- // If we can't get the remote location, we should disconnect since nothing can be done with the provider
- try {
- Team.removeNatureFromProject(project, CVSProviderPlugin.getTypeId(), Policy.monitorFor(null));
- } catch (TeamException ex) {
- CVSProviderPlugin.log(ex);
- }
- // We need to trigger a decorator refresh
- throw e;
- }
- }
-
- /**
- * @see ITeamProvider#hasRemote(IResource)
- * XXX to be removed when sync methods are removed from ITeamProvider
- */
- public boolean hasRemote(IResource resource) {
- try {
- ICVSResource cvsResource = workspaceRoot.getCVSResourceFor(resource);
- int type = resource.getType();
- if(type!=IResource.FILE) {
- if(type==IResource.PROJECT) {
- return ((ICVSFolder)cvsResource).isCVSFolder();
- } else {
- return cvsResource.isManaged();
- }
- } else {
- ResourceSyncInfo info = cvsResource.getSyncInfo();
- if(info!=null) {
- return !info.isAdded();
- } else {
- return false;
- }
- }
- } catch(CVSException e) {
- return false;
- }
- }
-
- /**
- * @see ITeamProvider#isLocallyCheckedOut(IResource)
- * XXX to be removed when sync methods are removed from ITeamProvider
- */
- public boolean isCheckedOut(IResource resource) {
- ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource);
- return cvsResource.isManaged();
- }
-
- /*
- * Use specialiazed tagging to move all local changes (including additions and
- * deletions) to the specified branch.
- */
- public void makeBranch(IResource[] resources, CVSTag versionTag, CVSTag branchTag, boolean moveToBranch, boolean eclipseWay, IProgressMonitor monitor) throws TeamException {
-
- // Determine the total amount of work
- int totalWork = 10 + (versionTag!= null ? 60 : 40) + (moveToBranch ? 20 : 0);
- monitor.beginTask(Policy.bind("CVSTeamProvider.makeBranch"), totalWork); //$NON-NLS-1$
- try {
-
- // Determine which tag command to used depending on whether the Eclipse specific
- // method of branching is requested
- Tag tagCommand = Command.TAG;
- if (eclipseWay) {
- tagCommand = Command.CUSTOM_TAG;
- }
-
- // Build the arguments list
- String[] arguments = getValidArguments(resources, Command.NO_LOCAL_OPTIONS);
-
- // Tag the remote resources
- Session s = new Session(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot());
- try {
- s.open(Policy.subMonitorFor(monitor, 10));
-
- IStatus status;
- if (versionTag != null) {
- // Version using tag and braqnch using rtag
- status = tagCommand.execute(s,
- Command.NO_GLOBAL_OPTIONS,
- Command.NO_LOCAL_OPTIONS,
- versionTag,
- arguments,
- null,
- Policy.subMonitorFor(monitor, 40));
- if (status.getCode() != CVSStatus.SERVER_ERROR) {
- // XXX Could use RTAG here when it works
- status = tagCommand.execute(s,
- Command.NO_GLOBAL_OPTIONS,
- Command.NO_LOCAL_OPTIONS,
- branchTag,
- arguments,
- null,
- Policy.subMonitorFor(monitor, 20));
- }
- } else {
- // Just branch using tag
- status = tagCommand.execute(s,
- Command.NO_GLOBAL_OPTIONS,
- Command.NO_LOCAL_OPTIONS,
- branchTag,
- arguments,
- null,
- Policy.subMonitorFor(monitor, 40));
-
- }
- if (status.getCode() == CVSStatus.SERVER_ERROR) {
- throw new CVSServerException(status);
- }
- } finally {
- s.close();
- }
-
- // Set the tag of the local resources to the branch tag (The update command will not
- // properly update "cvs added" and "cvs removed" resources so a custom visitor is used
- if (moveToBranch) {
- if (eclipseWay) {
- setTag(resources, branchTag, Policy.subMonitorFor(monitor, 20));
- } else {
- update(resources, Command.NO_LOCAL_OPTIONS, branchTag, true /*createBackups*/, Policy.subMonitorFor(monitor, 20));
- }
- }
- } finally {
- monitor.done();
- }
- }
-
- /**
- * Update the sync info of the local resource associated with the sync element such that
- * the revision of the local resource matches that of the remote resource.
- * This will allow commits on the local resource to succeed.
- *
- * Only file resources can be merged.
- */
- public void merged(IRemoteSyncElement[] elements) throws TeamException {
- for (int i=0;i<elements.length;i++) {
- ((CVSRemoteSyncElement)elements[i]).makeOutgoing(Policy.monitorFor(null));
- }
- }
-
- /**
- * @see ITeamProvider#move(IResource, IPath, IProgressMonitor)
- */
- public void moved(IPath source, IResource resource, IProgressMonitor progress) throws TeamException {
- }
-
- /**
- * Set the comment to be used on the next checkin
- */
- public void setComment(String comment) {
- this.comment = comment;
- }
-
- /**
- * Set the connection method for the given resource's
- * project. If the conection method name is invalid (i.e.
- * no corresponding registered connection method), false is returned.
- */
- public boolean setConnectionInfo(IResource resource, String methodName, IUserInfo userInfo, IProgressMonitor monitor) throws TeamException {
- checkIsChild(resource);
- try {
- monitor.beginTask(Policy.bind("CVSTeamProvider.connectionInfo", project.getName()), 100); //$NON-NLS-1$
-
- if (!CVSRepositoryLocation.validateConnectionMethod(methodName))
- return false;
-
- // Get the original location
- ICVSRepositoryLocation location = workspaceRoot.getRemoteLocation();
-
- // Make a copy to work on
- CVSRepositoryLocation newLocation = CVSRepositoryLocation.fromString(location.getLocation());
- newLocation.setMethod(methodName);
- newLocation.setUserInfo(userInfo);
-
- // Validate that a connection can be made with the new location
- try {
- newLocation.validateConnection(Policy.subMonitorFor(monitor, 20));
- } catch (CVSException e) {
- // XXX We should really only do this if it didn't exist previously
- CVSProviderPlugin.getProvider().disposeRepository(newLocation);
- throw e;
- }
-
- // Add the location to the provider
- CVSProvider.getInstance().addRepository(newLocation);
-
- // Set the project to use the new Locations
- setRemoteRoot(newLocation, Policy.subMonitorFor(monitor, 80));
- return true;
- } finally {
- monitor.done();
- }
- }
-
- /*
- * This method sets the tag for a project.
- * It expects to be passed an InfiniteSubProgressMonitor
- */
- private void setTag(final IResource[] resources, final CVSTag tag, IProgressMonitor monitor) throws TeamException {
-
- workspaceRoot.getLocalRoot().run(new ICVSRunnable() {
- public void run(IProgressMonitor progress) throws CVSException {
- try {
- // 512 ticks gives us a maximum of 2048 which seems reasonable for folders and files in a project
- progress.beginTask(null, 100);
- final IProgressMonitor monitor = Policy.infiniteSubMonitorFor(progress, 100);
- monitor.beginTask(Policy.bind("CVSTeamProvider.folderInfo", project.getName()), 512); //$NON-NLS-1$
-
- // Visit all the children folders in order to set the root in the folder sync info
- for (int i = 0; i < resources.length; i++) {
- CVSWorkspaceRoot.getCVSResourceFor(resources[i]).accept(new ICVSResourceVisitor() {
- public void visitFile(ICVSFile file) throws CVSException {
- monitor.worked(1);
- ResourceSyncInfo info = file.getSyncInfo();
- if (info != null) {
- monitor.subTask(Policy.bind("CVSTeamProvider.updatingFile", info.getName())); //$NON-NLS-1$
- MutableResourceSyncInfo newInfo = info.cloneMutable();
- newInfo.setTag(tag);
- file.setSyncInfo(newInfo);
- }
- };
- public void visitFolder(ICVSFolder folder) throws CVSException {
- monitor.worked(1);
- FolderSyncInfo info = folder.getFolderSyncInfo();
- if (info != null) {
- monitor.subTask(Policy.bind("CVSTeamProvider.updatingFolder", info.getRepository())); //$NON-NLS-1$
- folder.setFolderSyncInfo(new FolderSyncInfo(info.getRepository(), info.getRoot(), tag, info.getIsStatic()));
- folder.acceptChildren(this);
- }
- };
- });
- }
- } finally {
- progress.done();
- }
- }
- }, monitor);
- }
-
- /**
- * Tag the resources in the CVS repository with the given tag.
- *
- * The returned IStatus will be a status containing any errors or warnings.
- * If the returned IStatus is a multi-status, the code indicates the severity.
- * Possible codes are:
- * CVSStatus.OK - Nothing to report
- * CVSStatus.SERVER_ERROR - The server reported an error
- * any other code - warning messages received from the server
- */
- public IStatus tag(IResource[] resources, int depth, CVSTag tag, IProgressMonitor progress) {
-
- // Build the local options
- List localOptions = new ArrayList();
- // If the depth is not infinite, we want the -l option
- if (depth != IResource.DEPTH_INFINITE)
- localOptions.add(Tag.DO_NOT_RECURSE);
- LocalOption[] commandOptions = (LocalOption[])localOptions.toArray(new LocalOption[localOptions.size()]);
-
- IStatus status;
- try {
- // Build the arguments list
- String[] arguments = getValidArguments(resources, commandOptions);
-
- Session s = new Session(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot());
- progress.beginTask(null, 100);
- try {
- // Opening the session takes 20% of the time
- s.open(Policy.subMonitorFor(progress, 20));
- status = Command.TAG.execute(s,
- Command.NO_GLOBAL_OPTIONS,
- commandOptions,
- tag,
- arguments,
- null,
- Policy.subMonitorFor(progress, 80));
- } finally {
- s.close();
- progress.done();
- }
- } catch(CVSException e) {
- status = e.getStatus();
- }
- return status;
- }
-
- /**
- * Currently, we support only the optimistic model so uncheckout dores nothing.
- *
- * @see ITeamProvider#uncheckout(IResource[], int, IProgressMonitor)
- */
- public void uncheckout(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException {
- }
-
- /**
- * Generally useful update.
- *
- * The tag parameter determines any stickyness after the update is run. If tag is null, any tagging on the
- * resources being updated remain the same. If the tag is a branch, version or date tag, then the resources
- * will be appropriatly tagged. If the tag is HEAD, then there will be no tag on the resources (same as -A
- * clear sticky option).
- *
- * @param createBackups if true, creates .# files for updated files
- */
- public void update(IResource[] resources, LocalOption[] options, CVSTag tag, boolean createBackups, IProgressMonitor progress) throws TeamException {
- // Build the local options
- List localOptions = new ArrayList();
-
- // Use the appropriate tag options
- if (tag != null) {
- localOptions.add(Update.makeTagOption(tag));
- }
-
- // Build the arguments list
- localOptions.addAll(Arrays.asList(options));
- LocalOption[] commandOptions = (LocalOption[])localOptions.toArray(new LocalOption[localOptions.size()]);
- String[] arguments = getValidArguments(resources, commandOptions);
-
- IStatus status;
- Session s = new Session(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot());
- progress.beginTask(null, 100);
- try {
- // Opening the session takes 20% of the time
- s.open(Policy.subMonitorFor(progress, 20));
- status = Command.UPDATE.execute(s, Command.NO_GLOBAL_OPTIONS, commandOptions, arguments,
- null, Policy.subMonitorFor(progress, 80), createBackups);
- } finally {
- progress.done();
- s.close();
- }
- if (status.getCode() == CVSStatus.SERVER_ERROR) {
- // XXX diff errors??
- throw new CVSServerException(status);
- }
- }
-
- public static String getMessageFor(Exception e) {
- String message = Policy.bind(e.getClass().getName(), new Object[] {e.getMessage()});
- if (message.equals(e.getClass().getName()))
- message = Policy.bind("CVSTeamProvider.exception", new Object[] {e.toString()}); //$NON-NLS-1$
- return message;
- }
-
-
- /*
- * @see ITeamProvider#refreshState(IResource[], int, IProgressMonitor)
- */
- public void refreshState(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException {
- Assert.isTrue(false);
- }
- /*
- * @see ITeamProvider#isOutOfDate(IResource)
- * XXX to be removed when sync methods are removed from ITeamProvider
- */
- public boolean isOutOfDate(IResource resource) {
- Assert.isTrue(false);
- return false;
- }
-
- /*
- * @see ITeamProvider#isDirty(IResource)
- */
- public boolean isDirty(IResource resource) {
- Assert.isTrue(false);
- return false;
- }
-
- public CVSWorkspaceRoot getCVSWorkspaceRoot() {
- return workspaceRoot;
- }
-
- /*
- * Generate an exception if the resource is not a child of the project
- */
- private void checkIsChild(IResource resource) throws CVSException {
- if (!isChildResource(resource))
- throw new CVSException(new Status(IStatus.ERROR, CVSProviderPlugin.ID, TeamException.UNABLE,
- Policy.bind("CVSTeamProvider.invalidResource", //$NON-NLS-1$
- new Object[] {resource.getFullPath().toString(), project.getName()}),
- null));
- }
-
- /*
- * Get the arguments to be passed to a commit or update
- */
- private String[] getValidArguments(IResource[] resources, LocalOption[] options) throws CVSException {
- List arguments = new ArrayList(resources.length);
- for (int i=0;i<resources.length;i++) {
- checkIsChild(resources[i]);
- IPath cvsPath = resources[i].getFullPath().removeFirstSegments(1);
- if (cvsPath.segmentCount() == 0) {
- arguments.add(Session.CURRENT_LOCAL_FOLDER);
- } else {
- arguments.add(cvsPath.toString());
- }
- }
- return (String[])arguments.toArray(new String[arguments.size()]);
- }
-
- /*
- * This method expects to be passed an InfiniteSubProgressMonitor
- */
- public void setRemoteRoot(ICVSRepositoryLocation location, IProgressMonitor monitor) throws TeamException {
-
- // Check if there is a differnece between the new and old roots
- final String root = location.getLocation();
- if (root.equals(workspaceRoot.getRemoteLocation()))
- return;
-
- try {
- workspaceRoot.getLocalRoot().run(new ICVSRunnable() {
- public void run(IProgressMonitor progress) throws CVSException {
- try {
- // 256 ticks gives us a maximum of 1024 which seems reasonable for folders is a project
- progress.beginTask(null, 100);
- final IProgressMonitor monitor = Policy.infiniteSubMonitorFor(progress, 100);
- monitor.beginTask(Policy.bind("CVSTeamProvider.folderInfo", project.getName()), 256); //$NON-NLS-1$
-
- // Visit all the children folders in order to set the root in the folder sync info
- workspaceRoot.getLocalRoot().accept(new ICVSResourceVisitor() {
- public void visitFile(ICVSFile file) throws CVSException {};
- public void visitFolder(ICVSFolder folder) throws CVSException {
- monitor.worked(1);
- FolderSyncInfo info = folder.getFolderSyncInfo();
- if (info != null) {
- monitor.subTask(Policy.bind("CVSTeamProvider.updatingFolder", info.getRepository())); //$NON-NLS-1$
- folder.setFolderSyncInfo(new FolderSyncInfo(info.getRepository(), root, info.getTag(), info.getIsStatic()));
- folder.acceptChildren(this);
- }
- };
- });
- } finally {
- progress.done();
- }
- }
- }, monitor);
- } finally {
- monitor.done();
- }
- }
-
- /*
- * Helper to indicate if the resource is a child of the receiver's project
- */
- private boolean isChildResource(IResource resource) {
- return resource.getProject().getName().equals(project.getName());
- }
-
- private static TeamException wrapException(CoreException e) {
- return new TeamException(statusFor(e));
- }
-
- private static IStatus statusFor(CoreException e) {
- // We should be taking out any status from the CVSException
- // and creating an array of IStatus!
- return new Status(IStatus.ERROR, CVSProviderPlugin.ID, TeamException.UNABLE, getMessageFor(e), e);
- }
-
- public void configureProject() throws CoreException {
- CVSProviderPlugin.broadcastProjectConfigured(getProject());
- }
- /**
- * Sets the keyword substitution mode for the specified resources.
- * <p>
- * Applies the following rules in order:<br>
- * <ul>
- * <li>If a file is not managed, skips it.</li>
- * <li>If a file is not changing modes, skips it.</li>
- * <li>If a file is being changed from binary to text, corrects line delimiters
- * then commits it, then admins it.</li>
- * <li>If a file is added, changes the resource sync information locally.</li>
- * <li>Otherwise commits the file (with FORCE to create a new revision), then admins it.</li>
- * </ul>
- * All files that are admin'd are committed with FORCE to prevent other developers from
- * casually trying to commit pending changes to the repository without first checking out
- * a new copy. This is not a perfect solution, as they could just as easily do an UPDATE
- * and not obtain the new keyword sync info.
- * </p>
- *
- * @param changeSet a map from IFile to KSubstOption
- * @param monitor the progress monitor
- * @return a status code indicating success or failure of the operation
- *
- * @throws TeamException
- */
- public IStatus setKeywordSubstitution(final Map /* from IFile to KSubstOption */ changeSet,
- IProgressMonitor monitor) throws TeamException {
- final IStatus[] result = new IStatus[] { ICommandOutputListener.OK };
- workspaceRoot.getLocalRoot().run(new ICVSRunnable() {
- public void run(final IProgressMonitor monitor) throws CVSException {
- final Map /* from KSubstOption to List of String */ filesToAdmin = new HashMap();
- final List /* of String */ filesToCommit = new ArrayList();
- final Collection /* of ICVSFile */ filesToCommitAsText = new HashSet(); // need fast lookup
-
- /*** determine the resources to be committed and/or admin'd ***/
- for (Iterator it = changeSet.entrySet().iterator(); it.hasNext();) {
- Map.Entry entry = (Map.Entry) it.next();
- IFile file = (IFile) entry.getKey();
- KSubstOption toKSubst = (KSubstOption) entry.getValue();
-
- // only set keyword substitution if resource is a managed file
- checkIsChild(file);
- ICVSFile mFile = CVSWorkspaceRoot.getCVSFileFor(file);
- if (! mFile.isManaged()) continue;
-
- // only set keyword substitution if new differs from actual
- ResourceSyncInfo info = mFile.getSyncInfo();
- KSubstOption fromKSubst = info.getKeywordMode();
- if (toKSubst.equals(fromKSubst)) continue;
-
- // change resource sync info immediately for an outgoing addition
- if (info.isAdded()) {
- MutableResourceSyncInfo newInfo = info.cloneMutable();
- newInfo.setKeywordMode(toKSubst);
- mFile.setSyncInfo(newInfo);
- continue;
- }
-
- // nothing do to for deletions
- if (info.isDeleted()) continue;
-
- // file exists remotely so we'll have to commit it
- String remotePath = mFile.getRelativePath(workspaceRoot.getLocalRoot());
- if (fromKSubst.isBinary() && ! toKSubst.isBinary()) {
- // converting from binary to text
- cleanLineDelimiters(file, IS_CRLF_PLATFORM, new NullProgressMonitor()); // XXX need better progress monitoring
- // remember to commit the cleaned resource as text before admin
- filesToCommitAsText.add(mFile);
- }
- // force a commit to bump the revision number
- makeDirty(file);
- filesToCommit.add(remotePath);
- // remember to admin the resource
- List list = (List) filesToAdmin.get(toKSubst);
- if (list == null) {
- list = new ArrayList();
- filesToAdmin.put(toKSubst, list);
- }
- list.add(remotePath);
- }
-
- /*** commit then admin the resources ***/
- // compute the total work to be performed
- int totalWork = filesToCommit.size();
- for (Iterator it = filesToAdmin.values().iterator(); it.hasNext();) {
- List list = (List) it.next();
- totalWork += list.size();
- }
- if (totalWork != 0) {
- Session s = new Session(workspaceRoot.getRemoteLocation(), workspaceRoot.getLocalRoot());
- monitor.beginTask(Policy.bind("CVSTeamProvider.settingKSubst"), 5 + totalWork); //$NON-NLS-1$
- try {
- s.open(Policy.subMonitorFor(monitor, 5));
-
- // commit files that changed from binary to text
- // NOTE: The files are committed as text with conversions even if the
- // resource sync info still says "binary".
- if (filesToCommit.size() != 0) {
- s.setTextTransferOverride(filesToCommitAsText);
- result[0] = Command.COMMIT.execute(s, Command.NO_GLOBAL_OPTIONS,
- new LocalOption[] { Commit.DO_NOT_RECURSE, Commit.FORCE,
- Commit.makeArgumentOption(Command.MESSAGE_OPTION, comment) },
- (String[]) filesToCommit.toArray(new String[filesToCommit.size()]),
- null, Policy.subMonitorFor(monitor, filesToCommit.size()));
- s.setTextTransferOverride(null);
- // if errors were encountered, abort
- if (! result[0].isOK()) return;
- }
-
- // admin files that changed keyword substitution mode
- // NOTE: As confirmation of the completion of a command, the server replies
- // with the RCS command output if a change took place. Rather than
- // assume that the command succeeded, we listen for these lines
- // and update the local ResourceSyncInfo for the particular files that
- // were actually changed remotely.
- for (Iterator it = filesToAdmin.entrySet().iterator(); it.hasNext();) {
- Map.Entry entry = (Map.Entry) it.next();
- KSubstOption toKSubst = (KSubstOption) entry.getKey();
- List list = (List) entry.getValue();
- // do it
- result[0] = Command.ADMIN.execute(s, Command.NO_GLOBAL_OPTIONS,
- new LocalOption[] { toKSubst },
- (String[]) list.toArray(new String[list.size()]),
- new AdminKSubstListener(toKSubst),
- Policy.subMonitorFor(monitor, list.size()));
- // if errors were encountered, abort
- if (! result[0].isOK()) return;
- }
- } finally {
- s.close();
- monitor.done();
- }
- }
- }
- }, Policy.monitorFor(monitor));
- return result[0];
- }
-
- /**
- * Fixes the line delimiters in the local file to reflect the platform's
- * native encoding. Performs CR/LF -> LF or LF -> CR/LF conversion
- * depending on the platform but does not affect delimiters that are
- * already correctly encoded.
- */
- public static void cleanLineDelimiters(IFile file, boolean useCRLF, IProgressMonitor progress)
- throws CVSException {
- try {
- // convert delimiters in memory
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- InputStream is = new BufferedInputStream(file.getContents());
- try {
- is = new CRLFtoLFInputStream(is);
- if (useCRLF) is = new LFtoCRLFInputStream(is);
- for (int b; (b = is.read()) != -1;) bos.write(b);
- bos.close();
- } finally {
- is.close();
- }
- // write file back to disk with corrected delimiters if changes were made
- ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
- file.setContents(bis, false /*force*/, false /*keepHistory*/, progress);
- } catch (CoreException e) {
- throw CVSException.wrapException(file, Policy.bind("CVSTeamProvider.cleanLineDelimitersException"), e); //$NON-NLS-1$
- } catch (IOException e) {
- throw CVSException.wrapException(file, Policy.bind("CVSTeamProvider.cleanLineDelimitersException"), e); //$NON-NLS-1$
- }
- }
-
- /*
- * Marks a file as dirty.
- */
- private static void makeDirty(IFile file) throws CVSException {
- ICVSFile mFile = CVSWorkspaceRoot.getCVSFileFor(file);
- mFile.setTimeStamp(null /*set the timestamp to current time*/);
- }
-
- /*
- * @see RepositoryProvider#getID()
- */
- public String getID() {
- return CVSProviderPlugin.getTypeId();
- }
-
- /*
- * @see RepositoryProvider#getMoveDeleteHook()
- */
- public IMoveDeleteHook getMoveDeleteHook() {
- return moveDeleteHook;
- }
-
- /*
- * Return the currently registered Move/Delete Hook
- */
- public static IMoveDeleteHook getRegisteredMoveDeleteHook() {
- return moveDeleteHook;
- }
-
- /*
- * Set the Move/Delete hook of the CVS Team Provider. This is for internal use by CVS only.
- * It is not to be used by other clients
- */
- public static void setMoveDeleteHook(IMoveDeleteHook hook) {
- moveDeleteHook = hook;
- }
-} \ No newline at end of file

Back to the top