Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Eblen2012-05-07 14:07:39 +0000
committerJohn Eblen2012-05-07 14:57:33 +0000
commiteb2583977524973bff844e0db2b55b270b96b4e5 (patch)
tree243b7b3e5698bc8cbda6f24d96b5e5be0dbd7548 /rdt/org.eclipse.ptp.rdt.sync.git.core
parent2e3ac737e9d5883ba5848372fe6d4049a51db5b1 (diff)
downloadorg.eclipse.ptp-eb2583977524973bff844e0db2b55b270b96b4e5.tar.gz
org.eclipse.ptp-eb2583977524973bff844e0db2b55b270b96b4e5.tar.xz
org.eclipse.ptp-eb2583977524973bff844e0db2b55b270b96b4e5.zip
Final part of fix for bug 371507 - Projects should be relocatable
To support renaming and copying of sync projects: 1) Simplify BuildConfigurationManager: a) Make sync providers flexible (can sync multiple projects and configurations) b) Thus, remove need for copying and modifying service configurations and having multiple ones per project. c) Save CDT build configuration settings (build scenarios) to CDT (.cproject file) d) Deprecate direct access to service configurations 2) Use macro to support relocation of Workspace build configuration 3) Introduce new sync mode (UNAVAILABLE) to avoid initialization problems
Diffstat (limited to 'rdt/org.eclipse.ptp.rdt.sync.git.core')
-rw-r--r--rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/GitRemoteSyncConnection.java7
-rw-r--r--rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/GitServiceProvider.java178
-rw-r--r--rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/messages/Messages.java1
-rw-r--r--rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/messages/messages.properties3
4 files changed, 90 insertions, 99 deletions
diff --git a/rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/GitRemoteSyncConnection.java b/rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/GitRemoteSyncConnection.java
index 88beaa0bf..a608b0b59 100644
--- a/rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/GitRemoteSyncConnection.java
+++ b/rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/GitRemoteSyncConnection.java
@@ -643,6 +643,13 @@ public class GitRemoteSyncConnection {
}
/**
+ * @return the project
+ */
+ public IProject getProject() {
+ return project;
+ }
+
+ /**
* @return the connection (IRemoteConnection)
*/
public IRemoteConnection getConnection() {
diff --git a/rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/GitServiceProvider.java b/rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/GitServiceProvider.java
index 50e5e020d..7c97bedd3 100644
--- a/rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/GitServiceProvider.java
+++ b/rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/GitServiceProvider.java
@@ -11,7 +11,10 @@
package org.eclipse.ptp.rdt.sync.git.core;
import java.io.ByteArrayInputStream;
+import java.util.Collections;
import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
@@ -21,13 +24,12 @@ import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IResourceVisitor;
-import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
-import org.eclipse.ptp.rdt.sync.core.RDTSyncCorePlugin;
+import org.eclipse.ptp.rdt.sync.core.BuildScenario;
import org.eclipse.ptp.rdt.sync.core.SyncFileFilter;
import org.eclipse.ptp.rdt.sync.core.SyncFlag;
import org.eclipse.ptp.rdt.sync.core.SyncManager;
@@ -47,19 +49,61 @@ public class GitServiceProvider extends ServiceProvider implements ISyncServiceP
private static final String GIT_CONNECTION_NAME = "connectionName"; //$NON-NLS-1$
private static final String GIT_SERVICES_ID = "servicesId"; //$NON-NLS-1$
- private static final String GIT_PROJECT_NAME = "projectName"; //$NON-NLS-1$
- private IProject fProject = null;
private String fLocation = null;
private IRemoteConnection fConnection = null;
- private GitRemoteSyncConnection fSyncConnection = null;
- private boolean syncInfoChanged = false; // Indicates that fSyncConnection needs to be re-initialized
private boolean hasBeenSynced = false;
private static final ReentrantLock syncLock = new ReentrantLock();
- private final ReentrantLock providerLock = new ReentrantLock();
private Integer fWaitingThreadsCount = 0;
private Integer syncTaskId = -1; // ID for most recent synchronization task, functions as a time-stamp
private int finishedSyncTaskId = -1; // all synchronizations up to this ID (including it) have finished
+
+ // Simple pair class for bundling a project and build scenario.
+ // Since we use this as a key, equality testing is important.
+ private static class ProjectAndScenario {
+ private IProject project;
+ private BuildScenario scenario;
+
+ ProjectAndScenario(IProject p, BuildScenario bs) {
+ project = p;
+ scenario = bs;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((project == null) ? 0 : project.hashCode());
+ result = prime * result
+ + ((scenario == null) ? 0 : scenario.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ProjectAndScenario other = (ProjectAndScenario) obj;
+ if (project == null) {
+ if (other.project != null)
+ return false;
+ } else if (!project.equals(other.project))
+ return false;
+ if (scenario == null) {
+ if (other.scenario != null)
+ return false;
+ } else if (!scenario.equals(other.scenario))
+ return false;
+ return true;
+ }
+ }
+ private Map<ProjectAndScenario, GitRemoteSyncConnection> syncConnectionMap = Collections.synchronizedMap(
+ new HashMap<ProjectAndScenario, GitRemoteSyncConnection>());
/**
* Get the remote directory that will be used for synchronization
@@ -74,21 +118,6 @@ public class GitServiceProvider extends ServiceProvider implements ISyncServiceP
}
/**
- * Get the project to be synchronized
- *
- * @return project
- */
- public IProject getProject() {
- if (fProject == null) {
- final String name = getString(GIT_PROJECT_NAME, null);
- if (name != null) {
- fProject = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
- }
- }
- return fProject;
- }
-
- /**
* Get the remote connection used for synchronization
*
* @return remote connection
@@ -125,7 +154,7 @@ public class GitServiceProvider extends ServiceProvider implements ISyncServiceP
* @see org.eclipse.ptp.services.core.IServiceProvider#isConfigured()
*/
public boolean isConfigured() {
- return getLocation() != null && getRemoteConnection() != null && getProject() != null;
+ return getLocation() != null && getRemoteConnection() != null;
}
/**
@@ -145,20 +174,6 @@ public class GitServiceProvider extends ServiceProvider implements ISyncServiceP
}
/**
- * Set the project that will be synchronized
- *
- * @param project
- * project to synchronize
- */
- public void setProject(IProject project) {
- if (fProject != null) {
- throw new RuntimeException(Messages.GSP_ChangeProjectError);
- }
- fProject = project;
- putString(GIT_PROJECT_NAME, project.getName());
- }
-
- /**
* set the remote connection used for synchronization
*
* @param conn
@@ -188,18 +203,15 @@ public class GitServiceProvider extends ServiceProvider implements ISyncServiceP
/*
* (non-Javadoc)
- *
- * @see org.eclipse.ptp.rdt.sync.core.serviceproviders.ISyncServiceProvider#
- * synchronize(org.eclipse.core.resources.IResourceDelta, org.eclipse.core.runtime.IProgressMonitor, boolean)
+ * @see org.eclipse.ptp.rdt.sync.core.serviceproviders.ISyncServiceProvider#synchronize(org.eclipse.core.resources.IProject, org.eclipse.core.resources.IResourceDelta, org.eclipse.ptp.rdt.sync.core.SyncFileFilter, org.eclipse.core.runtime.IProgressMonitor, java.util.EnumSet)
*/
- @SuppressWarnings("null")
- public void synchronize(IResourceDelta delta, SyncFileFilter fileFilter, IProgressMonitor monitor,
- EnumSet<SyncFlag> syncFlags) throws CoreException {
+ public void synchronize(final IProject project, BuildScenario buildScenario, IResourceDelta delta, SyncFileFilter fileFilter,
+ IProgressMonitor monitor, EnumSet<SyncFlag> syncFlags) throws CoreException {
SubMonitor progress = SubMonitor.convert(monitor, Messages.GSP_SyncTaskName, 130);
+
// On first sync, place .gitignore in directories. This is useful for folders that are already present and thus are never
// captured by a resource add or change event. (This can happen for projects converted to sync projects.)
if (!hasBeenSynced) {
- final IProject project = getProject();
project.accept(new IResourceVisitor() {
public boolean visit(IResource resource) throws CoreException {
if (irrelevantPath(resource.getFullPath().toString())) {
@@ -240,7 +252,7 @@ public class GitServiceProvider extends ServiceProvider implements ISyncServiceP
// Add .gitignore to empty directories
if (delta.getResource().getType() == IResource.FOLDER
&& (delta.getKind() == IResourceDelta.ADDED || delta.getKind() == IResourceDelta.CHANGED)) {
- IFile emptyFile = getProject().getFile(
+ IFile emptyFile = project.getFile(
delta.getResource().getProjectRelativePath().addTrailingSeparator() + ".gitignore"); //$NON-NLS-1$
try {
if (!(emptyFile.exists())) {
@@ -323,42 +335,20 @@ public class GitServiceProvider extends ServiceProvider implements ISyncServiceP
return;
}
- // Safely initialize or re-initialize sync connection. Note that only the thread with the sync lock can change the
- // fSyncConnection. To do so, it copies the sync information atomically first and then creates the connection.
- // Copying avoids having to lock the provider lock during the initialization, a rather involved operation that may
- // take other locks, such as the workspace lock.
- boolean initConnection = false;
- IRemoteConnection conn = null;
- IProject project = null;
- String remoteDir = null;
- providerLock.lock();
- try {
- if (fSyncConnection == null || syncInfoChanged) {
- if (fSyncConnection != null) {
- fSyncConnection.close();
- fSyncConnection = null;
- }
- syncInfoChanged = false;
- initConnection = true;
- project = this.getProject();
- conn = this.getRemoteConnection();
- remoteDir = this.getLocation();
- }
- } finally {
- providerLock.unlock();
+ if (buildScenario == null) {
+ throw new RuntimeException(Messages.GitServiceProvider_3 + project.getName());
}
-
- if (initConnection && (project == null || conn == null || remoteDir == null)) {
- RDTSyncCorePlugin.log(Messages.GitServiceProvider_0);
- } else if (initConnection) {
- fSyncConnection = new GitRemoteSyncConnection(project, conn, project.getLocation().toString(), remoteDir, fileFilter, progress);
- } else {
- fSyncConnection.setFileFilter(fileFilter);
+ ProjectAndScenario pas = new ProjectAndScenario(project, buildScenario);
+ if (!syncConnectionMap.containsKey(pas)) {
+ syncConnectionMap.put(pas, new GitRemoteSyncConnection(project, buildScenario.getRemoteConnection(),
+ project.getLocation().toString(), buildScenario.getLocation(project), fileFilter, progress));
}
-
+ GitRemoteSyncConnection fSyncConnection = syncConnectionMap.get(pas);
+ fSyncConnection.setFileFilter(fileFilter);
+
// Open remote connection if necessary
- if (this.getRemoteConnection().isOpen() == false) {
- this.getRemoteConnection().open(progress.newChild(10));
+ if (buildScenario.getRemoteConnection().isOpen() == false) {
+ buildScenario.getRemoteConnection().open(progress.newChild(10));
}
// This synchronization operation will include all tasks up to current syncTaskId
@@ -379,10 +369,10 @@ public class GitServiceProvider extends ServiceProvider implements ISyncServiceP
finishedSyncTaskId = willFinishTaskId;
// TODO: Review exception handling
} catch (final RemoteSyncException e) {
- this.handleRemoteSyncException(e, syncFlags);
+ this.handleRemoteSyncException(project, e, syncFlags);
return;
} catch (RemoteConnectionException e) {
- this.handleRemoteSyncException(new RemoteSyncException(e), syncFlags);
+ this.handleRemoteSyncException(project, new RemoteSyncException(e), syncFlags);
return;
} finally {
syncLock.unlock();
@@ -390,12 +380,10 @@ public class GitServiceProvider extends ServiceProvider implements ISyncServiceP
// Sync successful - re-enable error messages. This is really UI code, but there is no way at the moment to notify UI
// of a successful sync.
- SyncManager.setShowErrors(getProject(), true);
-
- IProject project = this.getProject();
- if (project != null) {
- project.refreshLocal(IResource.DEPTH_INFINITE, progress.newChild(20));
- }
+ SyncManager.setShowErrors(project, true);
+
+ // Refresh after sync to display changes
+ project.refreshLocal(IResource.DEPTH_INFINITE, progress.newChild(20));
} finally {
if (monitor != null) {
monitor.done();
@@ -413,7 +401,8 @@ public class GitServiceProvider extends ServiceProvider implements ISyncServiceP
* @throws RemoteSyncException
* for non-forced syncs
*/
- private void handleRemoteSyncException(RemoteSyncException e, EnumSet<SyncFlag> syncFlags) throws RemoteSyncException {
+ private void handleRemoteSyncException(IProject project, RemoteSyncException e, EnumSet<SyncFlag> syncFlags)
+ throws RemoteSyncException {
if (syncFlags == SyncFlag.NO_FORCE) {
throw e;
}
@@ -423,10 +412,10 @@ public class GitServiceProvider extends ServiceProvider implements ISyncServiceP
// RemoteSyncException is generally used by either creating a new exception with a message describing the problem or by
// embedding another type of error. So we need to decide which message to use.
if ((e.getMessage() != null && e.getMessage().length() > 0) || e.getCause() == null) {
- message = Messages.GSP_SyncErrorMessage + this.getProject().getName()
+ message = Messages.GSP_SyncErrorMessage + project.getName()
+ ":" + endOfLineChar + endOfLineChar + e.getMessage(); //$NON-NLS-1$
} else {
- message = Messages.GSP_SyncErrorMessage + this.getProject().getName()
+ message = Messages.GSP_SyncErrorMessage + project.getName()
+ ":" + endOfLineChar + endOfLineChar + e.getCause().getMessage(); //$NON-NLS-1$
}
@@ -473,11 +462,8 @@ public class GitServiceProvider extends ServiceProvider implements ISyncServiceP
* @see org.eclipse.ptp.rdt.core.serviceproviders.IRemoteExecutionServiceProvider#setRemoteToolsConnection()
*/
public void setRemoteToolsConnection(IRemoteConnection connection) {
- providerLock.lock();
fConnection = connection;
putString(GIT_CONNECTION_NAME, connection.getName());
- syncInfoChanged = true;
- providerLock.unlock();
}
/*
@@ -486,18 +472,14 @@ public class GitServiceProvider extends ServiceProvider implements ISyncServiceP
* @see org.eclipse.ptp.rdt.core.serviceproviders.IRemoteExecutionServiceProvider#setConfigLocation()
*/
public void setConfigLocation(String configLocation) {
- providerLock.lock();
fLocation = configLocation;
putString(GIT_LOCATION, configLocation);
- syncInfoChanged = true;
- providerLock.unlock();
}
@Override
public void close() {
- if (fSyncConnection != null) {
- fSyncConnection.close();
- fSyncConnection = null; // get reinitialized by next synchronize call
+ for (GitRemoteSyncConnection conn : syncConnectionMap.values()) {
+ conn.close();
}
}
}
diff --git a/rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/messages/Messages.java b/rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/messages/Messages.java
index a16ca9a15..a5640bfc4 100644
--- a/rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/messages/Messages.java
+++ b/rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/messages/Messages.java
@@ -39,6 +39,7 @@ public class Messages extends NLS {
public static String GitServiceProvider_0;
public static String GitServiceProvider_1;
public static String GitServiceProvider_2;
+ public static String GitServiceProvider_3;
static {
// initialize resource bundle
diff --git a/rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/messages/messages.properties b/rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/messages/messages.properties
index ad0455ef0..0932bd448 100644
--- a/rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/messages/messages.properties
+++ b/rdt/org.eclipse.ptp.rdt.sync.git.core/src/org/eclipse/ptp/rdt/sync/git/core/messages/messages.properties
@@ -32,4 +32,5 @@ GitRemoteSyncConnection_sync_local_to_remote=Sync local to remote...
GitRemoteSyncConnection_sync_remote_to_local=Sync remote to local...
GitServiceProvider_0=Unable to retrieve information needed to create sync connection
GitServiceProvider_1=Synchronization canceled
-GitServiceProvider_2=Synchronization interrupted \ No newline at end of file
+GitServiceProvider_2=Synchronization interrupted
+GitServiceProvider_3=Unable to find build scenario for project:

Back to the top