in source/com.microsoft.tfs.client.eclipse/src/com/microsoft/tfs/client/eclipse/project/ProjectConnectionManager.java [113:398]
ProjectConnectionManagerResult connect(final IProject project, final boolean disconnectOtherServers) {
Check.notNull(project, "project"); //$NON-NLS-1$
final ProjectManagerDataProvider dataProvider = ProjectManagerDataProviderFactory.getDataProvider();
if (project.isOpen() == false) {
return new ProjectConnectionManagerResult(
new Status(
Status.ERROR,
TFSEclipseClientPlugin.PLUGIN_ID,
0,
MessageFormat.format(
Messages.getString("ProjectConnectionManager.ProjectNotOpenFormat"), //$NON-NLS-1$
project.getName()),
null));
}
if (project.getLocation() == null) {
final String message = MessageFormat.format(
Messages.getString("ProjectConnectionManager.ProjectDoesNotHaveLocalFileSystemMappingFormat"), //$NON-NLS-1$
project.getName());
return new ProjectConnectionManagerResult(
new Status(Status.ERROR, TFSEclipseClientPlugin.PLUGIN_ID, 0, message, null));
}
WorkspaceInfo cachedWorkspace;
TFSRepository repository;
/*
* Lock the cachedWorkspaceLock when we fetch a cached workspace for
* this Project. We do this because if we cannot immediately locate a
* cached workspace, we may prompt the user to connect to their TFS
* Server in order to query workspaces (and thus refresh the workspace
* cache.) We want to let the workspace cache refresh before we query it
* again in a different thread, since its data will likely be complete.
*/
synchronized (cachedWorkspaceLock) {
cachedWorkspace = getCachedWorkspace(project);
if (cachedWorkspace == null) {
if (emptyCachedWorkspaceFailures) {
log.error(MessageFormat.format("Project {0} was not found in workspace cache", project.getName())); //$NON-NLS-1$
return new ProjectConnectionManagerResult(
new Status(
Status.ERROR,
TFSEclipseClientPlugin.PLUGIN_ID,
0,
MessageFormat.format(projectDoesNotHaveWorkingFolderMappingFormat, project.getName()),
null));
}
log.warn(MessageFormat.format("Project {0} was not found in workspace cache", project.getName())); //$NON-NLS-1$
/*
* If we cannot find a cached workspace, prompt the user to
* connect. This will allow us to query workspaces on the server
* and rebuild the workspace cache. Hold a lock on the
* cachedWorkspaceLock to prevent other threads from prompting
* for a damaged workspace cache.
*/
repository = connectRepository(project);
if (repository == null) {
/*
* Abort further connections to empty cached workspaces.
* Prevents us from prompting forever.
*/
emptyCachedWorkspaceFailures = true;
return new ProjectConnectionManagerResult(
new Status(
Status.ERROR,
TFSEclipseClientPlugin.PLUGIN_ID,
0,
MessageFormat.format(projectDoesNotHaveWorkingFolderMappingFormat, project.getName()),
null));
}
return new ProjectConnectionManagerResult(repository);
}
}
ProjectManagerRepositoryJob repositoryJob;
final WorkspaceKey workspaceKey = new WorkspaceKey(cachedWorkspace);
synchronized (connectionLock) {
/* We've already got a TFS Repository for this workspace */
if ((repository =
TFSEclipseClientPlugin.getDefault().getRepositoryManager().getRepository(cachedWorkspace)) != null) {
log.debug(MessageFormat.format(
"Project {0} can be connected to repository {1}", //$NON-NLS-1$
project.getName(),
repository));
return new ProjectConnectionManagerResult(repository);
}
/*
* See if we're already running a connection job for this workspace
*/
if ((repositoryJob = workspaceJobMap.get(workspaceKey)) == null) {
/* See if there already exists a connection for this profile. */
final URI connectionURI = cachedWorkspace.getServerURI();
TFSServer server;
if ((server = serverManager.getServer(connectionURI)) != null) {
log.debug(
MessageFormat.format("Project {0} will be connected to server {1}", project.getName(), server)); //$NON-NLS-1$
/*
* Do not obliterate the current repository if it's
* configured.
*/
if (repositoryManager.getDefaultRepository() != null && disconnectOtherServers == false) {
return new ProjectConnectionManagerResult(
new Status(
Status.ERROR,
TFSEclipseClientPlugin.PLUGIN_ID,
0,
MessageFormat.format(
projectWillNotBeConnectedExistingConnectionExistsFormat,
project.getName()),
null));
}
/*
* Hook up our workspace to this TFS Connection instead of
* building a new one.
*/
repositoryJob =
new ProjectManagerRepositoryJob(this, dataProvider, cachedWorkspace, server.getConnection());
repositoryJob.addJobChangeListener(repositoryJobChangeListener);
repositoryJob.schedule();
workspaceJobMap.put(workspaceKey, repositoryJob);
} else {
ProjectManagerConnectionJob connectionJob;
/*
* See if another thread is trying to connect this profile.
*/
if ((connectionJob = serverConnectionJobMap.get(connectionURI)) == null) {
/*
* Make sure the user hasn't cancelled connections for
* this cached workspace.
*/
synchronized (cachedWorkspaceLock) {
if (cachedWorkspaceFailures.contains(cachedWorkspace)) {
return new ProjectConnectionManagerResult(
new Status(
Status.ERROR,
TFSEclipseClientPlugin.PLUGIN_ID,
0,
MessageFormat.format(
projectWillNotBeConnectedPreviousConnectionCancelledFormat,
project.getName()),
null));
}
}
/*
* There is no connection going on to this server:
* before we build a server connection, ensure that
* there are no other server connections in the server
* manager.
*/
if (serverManager.getDefaultServer() != null) {
log.debug(
MessageFormat.format(
"Another connection already exists while connecting project {0}", //$NON-NLS-1$
project.getName()));
/*
* Do not prompt to disconnect from the other server
*/
if (disconnectOtherServers == false) {
return new ProjectConnectionManagerResult(
new Status(
Status.ERROR,
TFSEclipseClientPlugin.PLUGIN_ID,
0,
MessageFormat.format(
projectWillNotBeConnectedExistingConnectionExistsFormat,
project.getName()),
null));
}
/* Allow users to close the existing connection. */
final boolean retry = dataProvider.getConnectionConflictHandler().resolveServerConflict();
/*
* If the user cancelled the retry, or we still have
* a default server, fail.
*/
if (retry == false || serverManager.getDefaultServer() != null) {
log.debug(
MessageFormat.format(
"Cancelled connection for project {0}, another connection already exists", //$NON-NLS-1$
project.getName()));
return new ProjectConnectionManagerResult(
new Status(
Status.ERROR,
TFSEclipseClientPlugin.PLUGIN_ID,
0,
MessageFormat.format(
projectWillNotBeConnectedExistingConnectionExistsFormat,
project.getName()),
null));
}
}
connectionJob = new ProjectManagerCachedWorkspaceConnectionJob(
this,
dataProvider,
connectionURI,
cachedWorkspace);
connectionJob.addJobChangeListener(connectionJobChangeListener);
connectionJob.setSystem(true);
connectionJob.schedule();
serverConnectionJobMap.put(connectionURI, connectionJob);
}
log.debug(MessageFormat.format(
"Project {0} will be connected through connection job {1}", //$NON-NLS-1$
project.getName(),
connectionJob));
/*
* Now build a job that will realize the Workspace when this
* profile is connected.
*/
repositoryJob = new ProjectManagerRepositoryJob(this, dataProvider, cachedWorkspace, connectionJob);
repositoryJob.addJobChangeListener(repositoryJobChangeListener);
repositoryJob.schedule();
log.debug(
MessageFormat.format(
"Project {0} will be connected through repository realization job {1}", //$NON-NLS-1$
project.getName(),
repositoryJob));
workspaceJobMap.put(workspaceKey, repositoryJob);
}
}
}
/* Wait for the workspace connector job to finish. */
IStatus result;
try {
log.debug("Waiting for repository job to finish"); //$NON-NLS-1$
new ExtensionPointAsyncObjectWaiter().joinJob(repositoryJob);
result = repositoryJob.getResult();
} catch (final InterruptedException e) {
result =
new Status(
Status.ERROR,
TFSEclipseClientPlugin.PLUGIN_ID,
0,
MessageFormat.format(
Messages.getString("ProjectConnectionManager.CouldNotConnectToConnectionFormat"), //$NON-NLS-1$
getConnectionName(cachedWorkspace)),
e);
}
if (result == null) {
result = new Status(
Status.ERROR,
TFSEclipseClientPlugin.PLUGIN_ID,
0,
Messages.getString("ProjectConnectionManager.CouldNotExecuteProjectConnectionJobFormat"), //$NON-NLS-1$
null);
}
if (!result.isOK()) {
return new ProjectConnectionManagerResult(null, result);
}
repository = repositoryJob.getRepository();
return new ProjectConnectionManagerResult(repositoryJob.getRepository(), result);
}