diff options
Diffstat (limited to 'bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations')
3 files changed, 399 insertions, 0 deletions
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/AddOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/AddOperation.java new file mode 100644 index 000000000..27659080d --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/AddOperation.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ccvs.ui.operations; + +import java.util.*; + +import org.eclipse.core.resources.*; +import org.eclipse.core.runtime.*; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.internal.ccvs.core.*; +import org.eclipse.team.internal.ccvs.core.client.Command; +import org.eclipse.team.internal.ccvs.core.client.Session; +import org.eclipse.team.internal.ccvs.core.client.Command.KSubstOption; +import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption; +import org.eclipse.team.internal.ccvs.core.connection.CVSServerException; +import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; +import org.eclipse.team.internal.ccvs.ui.Policy; +import org.eclipse.ui.IWorkbenchPart; + +/** + * Performs a "cvs add" + */ +public class AddOperation extends RepositoryProviderOperation { + + public AddOperation(IWorkbenchPart part, IResource[] resources) { + super(part, resources); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.RepositoryProviderOperation#execute(org.eclipse.team.internal.ccvs.core.CVSTeamProvider, org.eclipse.core.resources.IResource[], org.eclipse.core.runtime.IProgressMonitor) + */ + protected void execute(CVSTeamProvider provider, IResource[] resources, IProgressMonitor monitor) throws CVSException, InterruptedException { + add(provider, resources, IResource.DEPTH_INFINITE, monitor); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#getTaskName() + */ + protected String getTaskName() { + return Policy.bind("AddAction.adding"); //$NON-NLS-1$ + } + + /* + * 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> + */ + private void add(CVSTeamProvider provider, IResource[] resources, int depth, IProgressMonitor progress) throws CVSException { + + // 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 CVSException[] eHolder = new CVSException[1]; + for (int i=0; i<resources.length; i++) { + + final IResource currentResource = resources[i]; + + try { + // Auto-add parents if they are not already managed + IContainer parent = currentResource.getParent(); + ICVSResource cvsParentResource = CVSWorkspaceRoot.getCVSResourceFor(parent); + while (parent.getType() != IResource.ROOT && parent.getType() != IResource.PROJECT && ! isManaged(cvsParentResource)) { + folders.add(cvsParentResource); + parent = parent.getParent(); + cvsParentResource = cvsParentResource.getParent(); + } + + // Auto-add children + final TeamException[] exception = new TeamException[] { null }; + currentResource.accept(new IResourceVisitor() { + public boolean visit(IResource resource) { + try { + 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 (! isManaged(mResource) && (currentResource.equals(resource) || ! mResource.isIgnored())) { + 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(mResource); + } else { + folders.add(mResource); + } + } + // Always return true and let the depth determine if children are visited + return true; + } catch (CVSException e) { + exception[0] = e; + return false; + } + } + }, depth, false); + if (exception[0] != null) { + throw exception[0]; + } + } 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]; + + // Add the folders, followed by files! + progress.beginTask(null, files.size() * 10 + (folders.isEmpty() ? 0 : 10)); + try { + if (!folders.isEmpty()) { + Session session = new Session(getRemoteLocation(provider), getLocalRoot(provider), true /* output to console */); + session.open(Policy.subMonitorFor(progress, 2), true /* open for modification */); + try { + IStatus status = Command.ADD.execute( + session, + Command.NO_GLOBAL_OPTIONS, + Command.NO_LOCAL_OPTIONS, + (ICVSResource[])folders.toArray(new ICVSResource[folders.size()]), + null, + Policy.subMonitorFor(progress, 8)); + if (status.getCode() == CVSStatus.SERVER_ERROR) { + throw new CVSServerException(status); + } + } finally { + session.close(); + } + } + for (Iterator it = files.entrySet().iterator(); it.hasNext();) { + Map.Entry entry = (Map.Entry) it.next(); + final KSubstOption ksubst = (KSubstOption) entry.getKey(); + final Set set = (Set) entry.getValue(); + Session session = new Session(getRemoteLocation(provider), getLocalRoot(provider), true /* output to console */); + session.open(Policy.subMonitorFor(progress, 2), true /* open for modification */); + try { + IStatus status = Command.ADD.execute( + session, + Command.NO_GLOBAL_OPTIONS, + new LocalOption[] { ksubst }, + (ICVSResource[])set.toArray(new ICVSResource[set.size()]), + null, + Policy.subMonitorFor(progress, 8)); + if (status.getCode() == CVSStatus.SERVER_ERROR) { + throw new CVSServerException(status); + } + } finally { + session.close(); + } + } + } finally { + progress.done(); + } + } + + /* + * Consider a folder managed only if it's also a CVS folder + */ + private boolean isManaged(ICVSResource cvsResource) throws CVSException { + return cvsResource.isManaged() && (!cvsResource.isFolder() || ((ICVSFolder)cvsResource).isCVSFolder()); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#getErrorMessage(org.eclipse.core.runtime.IStatus[], int) + */ + protected String getErrorMessage(IStatus[] failures, int totalOperations) { + return Policy.bind("AddAction.addFailed"); //$NON-NLS-1$ + } +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CommitOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CommitOperation.java new file mode 100644 index 000000000..052cac26e --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CommitOperation.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ccvs.ui.operations; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceVisitor; +import org.eclipse.core.runtime.*; +import org.eclipse.team.internal.ccvs.core.*; +import org.eclipse.team.internal.ccvs.core.client.*; +import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption; +import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; +import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; +import org.eclipse.team.internal.ccvs.ui.repo.RepositoryManager; +import org.eclipse.ui.IWorkbenchPart; + +/** + * Perform a "cvs commit" + */ +public class CommitOperation extends SingleCommandOperation { + + public CommitOperation(IWorkbenchPart part, IResource[] resources, LocalOption[] options) { + super(part, resources, options); + } + + /** + * Perform prompting for unadded resources and comment + * @param monitor a progess monitor + * @return <code>true</code> if execution should continue + */ + public boolean performPrompting(IProgressMonitor monitor) throws CVSException, InvocationTargetException, InterruptedException { + monitor.beginTask(null, 20); + IResource[] resourcesToBeAdded = promptForResourcesToBeAdded(Policy.subMonitorFor(monitor, 10)); + String comment = promptForComment(getResources()); + if (comment == null) return false; + addLocalOption(Commit.makeArgumentOption(Command.MESSAGE_OPTION, comment)); + if (resourcesToBeAdded.length > 0) { + new AddOperation(getPart(), resourcesToBeAdded) + .run(Policy.subMonitorFor(monitor, 10)); + } + setResources(getSharedResources(getResources())); + monitor.done(); + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.RepositoryProviderOperation#execute(org.eclipse.core.runtime.IProgressMonitor) + */ + public void execute(IProgressMonitor monitor) throws CVSException, InterruptedException { + // Ensure that a comment has been provided + if (!Command.MESSAGE_OPTION.isElementOf(getLocalOptions())) { + String comment = promptForComment(getResources()); + if (comment == null) return; + addLocalOption(Commit.makeArgumentOption(Command.MESSAGE_OPTION, comment)); + } + super.execute(monitor); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.SingleCommandOperation#executeCommand(org.eclipse.team.internal.ccvs.core.client.Session, org.eclipse.team.internal.ccvs.core.CVSTeamProvider, org.eclipse.team.internal.ccvs.core.ICVSResource[], org.eclipse.core.runtime.IProgressMonitor) + */ + protected IStatus executeCommand(Session session, CVSTeamProvider provider, ICVSResource[] resources, IProgressMonitor monitor) throws CVSException, InterruptedException { + return Command.COMMIT.execute(session, + Command.NO_GLOBAL_OPTIONS, + getLocalOptions(), + resources, + null, + monitor); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#handleErrors(org.eclipse.core.runtime.IStatus[]) + */ + protected void handleErrors(IStatus[] errors) throws CVSException { + // We are only concerned with server errors + List serverErrors = new ArrayList(); + for (int i = 0; i < errors.length; i++) { + IStatus status = errors[i]; + if (status.getCode() == CVSStatus.SERVER_ERROR) { + serverErrors.add(status); + } + } + if (serverErrors.isEmpty()) return; + super.handleErrors((IStatus[]) serverErrors.toArray(new IStatus[serverErrors.size()])); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#getTaskName() + */ + protected String getTaskName() { + return Policy.bind("RepositoryManager.committing"); //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#getErrorMessage(org.eclipse.core.runtime.IStatus[], int) + */ + protected String getErrorMessage(IStatus[] failures, int totalOperations) { + return Policy.bind("CommitAction.commitFailed"); //$NON-NLS-1$ + } + + private IResource[] getUnaddedResources(IResource[] resources, IProgressMonitor iProgressMonitor) throws CVSException { + final List unadded = new ArrayList(); + final CVSException[] exception = new CVSException[] { null }; + for (int i = 0; i < resources.length; i++) { + IResource resource = resources[i]; + // visit each resource deeply + try { + resource.accept(new IResourceVisitor() { + public boolean visit(IResource resource) throws CoreException { + ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource); + // skip ignored resources and their children + try { + if (cvsResource.isIgnored()) + return false; + // visit the children of shared resources + if (cvsResource.isManaged()) + return true; + if (cvsResource.isFolder() && ((ICVSFolder)cvsResource).isCVSFolder()) + return true; + } catch (CVSException e) { + exception[0] = e; + } + // don't add folders to avoid comitting empty folders + if (resource.getType() == IResource.FOLDER) + return true; + // file is unshared so record it + unadded.add(resource); + // no need to go into children because add is deep + return false; + } + }); + } catch (CoreException e) { + throw CVSException.wrapException(e); + } + if (exception[0] != null) throw exception[0]; + } + return (IResource[]) unadded.toArray(new IResource[unadded.size()]); + } + + protected IResource[] promptForResourcesToBeAdded(IProgressMonitor monitor) throws CVSException { + IResource[] unadded = getUnaddedResources(getResources(), monitor); + RepositoryManager manager = CVSUIPlugin.getPlugin().getRepositoryManager(); + return manager.promptForResourcesToBeAdded(getShell(), unadded); + } + + protected String promptForComment(IResource[] resourcesToCommit) { + RepositoryManager manager = CVSUIPlugin.getPlugin().getRepositoryManager(); + return manager.promptForComment(getShell(), resourcesToCommit); + } + + /* + * Return all resources in the provided collection that are shared with a repo + * @param resources + * @return IResource[] + */ + private IResource[] getSharedResources(IResource[] resources) throws CVSException { + List shared = new ArrayList(); + for (int i = 0; i < resources.length; i++) { + IResource resource = resources[i]; + ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource); + if (cvsResource.isManaged() + || (cvsResource.isFolder() && ((ICVSFolder)cvsResource).isCVSFolder())) { + shared.add(resource); + } + } + return (IResource[]) shared.toArray(new IResource[shared.size()]); + } +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/UpdateOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/UpdateOperation.java index 38bd65700..bf09a103b 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/UpdateOperation.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/UpdateOperation.java @@ -95,5 +95,27 @@ public class UpdateOperation extends SingleCommandOperation { protected ICommandOutputListener getCommandOutputListener() { return null; } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#handleErrors(org.eclipse.core.runtime.IStatus[]) + */ + protected void handleErrors(IStatus[] errors) throws CVSException { + // We are only concerned with server errors + List serverErrors = new ArrayList(); + for (int i = 0; i < errors.length; i++) { + IStatus status = errors[i]; + if (status.getCode() == CVSStatus.SERVER_ERROR) { + serverErrors.add(status); + } + } + if (serverErrors.isEmpty()) return; + super.handleErrors((IStatus[]) serverErrors.toArray(new IStatus[serverErrors.size()])); + } + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#getErrorMessage(org.eclipse.core.runtime.IStatus[], int) + */ + protected String getErrorMessage(IStatus[] failures, int totalOperations) { + return Policy.bind("UpdateAction.update"); //$NON-NLS-1$ + } } |