blob: af8b6e747d38f074f4bcb7a0d0d9d93473ac6e47 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2010 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.team.internal.ccvs.ui.operations;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.team.core.RepositoryProvider;
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.connection.CVSServerException;
import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
import org.eclipse.team.internal.ccvs.core.resources.RemoteFolderTree;
import org.eclipse.team.internal.ccvs.ui.CVSUIMessages;
import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
import org.eclipse.team.internal.ccvs.ui.Policy;
/**
* Create a folder and any missing parents in the repository
*/
public class ShareProjectOperation extends CVSOperation {
private ICVSRepositoryLocation location;
private IProject project;
private String moduleName;
private Shell shell;
public ShareProjectOperation(Shell shell, ICVSRepositoryLocation location, IProject project, String moduleName) {
super(null);
this.shell = shell;
this.moduleName = moduleName;
this.project = project;
this.location = location;
}
@Override
protected void execute(IProgressMonitor monitor) throws CVSException, InterruptedException {
try {
monitor.beginTask(getTaskName(), 100);
// Create the remote module
final ICVSRemoteFolder remote = createRemoteFolder(Policy.subMonitorFor(monitor, 50));
// Map the project to the module in a workspace runnable
final TeamException[] exception = new TeamException[] {null};
ResourcesPlugin.getWorkspace().run((IWorkspaceRunnable) monitor1 -> {
try {
mapProjectToRemoteFolder(remote, monitor1);
} catch (TeamException e) {
exception[0] = e;
}
}, ResourcesPlugin.getWorkspace().getRuleFactory().modifyRule(project), 0, Policy.subMonitorFor(monitor, 100));
if (exception[0] != null)
throw exception[0];
} catch (CoreException e) {
throw CVSException.wrapException(e);
} finally {
monitor.done();
}
}
/**
* Create the remote folder to which the project is being mapped
* (as well as any ancestors) and return it. If the remote folder does not
* exist remotely, this method will create it.
* @param monitor a progress monitor
* @return the existing remote folder to which the project is being mapped
* @throws CVSException
*/
protected ICVSRemoteFolder createRemoteFolder(IProgressMonitor monitor) throws CVSException {
String projectName = project.getName();
if (moduleName == null)
moduleName = projectName;
RemoteFolderTree root = new RemoteFolderTree(null, location, Path.EMPTY.toString(), null);
Path path = new Path(null, moduleName);
try {
monitor.beginTask(getTaskName(), 100 * path.segmentCount());
return ensureTreeExists(root, path, monitor);
} catch (TeamException e) {
throw CVSException.wrapException(e);
} finally {
monitor.done();
}
}
/**
* Map the project to the remote folder by associating the CVS
* Repository Provider with the project and, at the very least,
* assigning the folder sync info for the remote folder as the
* folder sync info for the project.
* @param remote the remote folder to which the project is being mapped
* @param monitor a progress monitor
* @throws CVSException
*/
protected void mapProjectToRemoteFolder(final ICVSRemoteFolder remote, IProgressMonitor monitor) throws TeamException {
monitor.beginTask(null, IProgressMonitor.UNKNOWN);
purgeAnyCVSFolders(Policy.subMonitorFor(monitor, IProgressMonitor.UNKNOWN));
// Link the project to the newly created module
monitor.subTask(NLS.bind(CVSUIMessages.ShareProjectOperation_3, new String[] { project.getName(), remote.getRepositoryRelativePath() }));
ICVSFolder folder = (ICVSFolder)CVSWorkspaceRoot.getCVSResourceFor(project);
folder.setFolderSyncInfo(remote.getFolderSyncInfo());
//Register it with Team. If it already is, no harm done.
RepositoryProvider.map(project, CVSProviderPlugin.getTypeId());
monitor.done();
}
/*
* Create handles for all the children in the moduleName path
*/
private RemoteFolderTree createChild(RemoteFolderTree parent, String name, IProgressMonitor monitor) throws CVSException, TeamException {
RemoteFolderTree child = new RemoteFolderTree(parent, name, location, new Path(null, parent.getRepositoryRelativePath()).append(name).toString(), null);
parent.setChildren(new ICVSRemoteResource[] { child });
if (child.exists(Policy.subMonitorFor(monitor, 50))) {
// The child exists so get the handle that was received from the server
return (RemoteFolderTree)parent.getFolder(name);
} else {
// Create the folder remotely
createFolder(child, Policy.subMonitorFor(monitor, 50));
return child;
}
}
/*
* Ensure that all the folders in the tree exist
*/
private ICVSRemoteFolder ensureTreeExists(RemoteFolderTree folder, IPath path, IProgressMonitor monitor) throws TeamException {
if (path.isEmpty()) return folder;
String name = path.segment(0);
RemoteFolderTree child = createChild(folder, name, monitor);
return ensureTreeExists(child, path.removeFirstSegments(1), monitor);
}
private void createFolder(RemoteFolderTree folder, IProgressMonitor monitor) throws TeamException {
Session s = new Session(location, folder.getParent());
s.open(monitor, true /* open for modification */);
try {
IStatus status = Command.ADD.execute(s,
Command.NO_GLOBAL_OPTIONS,
Command.NO_LOCAL_OPTIONS,
new String[] { folder.getName() },
null,
monitor);
// If we get a warning, the operation most likely failed so check that the status is OK
if (status.getCode() == CVSStatus.SERVER_ERROR || ! status.isOK()) {
throw new CVSServerException(status);
}
} finally {
s.close();
}
}
@Override
protected String getTaskName() {
return NLS.bind(CVSUIMessages.ShareProjectOperation_0, new String[] { project.getName(), moduleName });
}
/**
* @return Returns the project.
*/
public IProject getProject() {
return project;
}
@Override
public Shell getShell() {
return shell;
}
/**
* Purge any CVS folders.
*
* @param monitor a progress monitor
*/
private void purgeAnyCVSFolders(final IProgressMonitor monitor) {
try {
monitor.beginTask(null, IProgressMonitor.UNKNOWN);
ICVSFolder folder = CVSWorkspaceRoot.getCVSFolderFor(project);
folder.accept(new ICVSResourceVisitor() {
@Override
public void visitFile(ICVSFile file) throws CVSException {
// nothing to do for files
}
@Override
public void visitFolder(ICVSFolder folder) throws CVSException {
monitor.subTask(NLS.bind(CVSUIMessages.ShareProjectOperation_2, new String[] { folder.getIResource().getFullPath().toString() } ));
if (folder.isCVSFolder()) {
// for now, just unmanage
folder.unmanage(null);
}
}
}, true /* recurse */);
} catch (CVSException e) {
// log the exception and return null
CVSUIPlugin.log(e);
} finally {
monitor.done();
}
}
}