Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Valenta2003-10-03 14:40:01 +0000
committerMichael Valenta2003-10-03 14:40:01 +0000
commit0c99eae780ae585149301a910919c41ed1bd7658 (patch)
tree122bddd428f9cd89c5f4cd31b137408198010130
parentcc798d822d1dea89fd843f10d68d630c200a523c (diff)
downloadeclipse.platform.team-0c99eae780ae585149301a910919c41ed1bd7658.tar.gz
eclipse.platform.team-0c99eae780ae585149301a910919c41ed1bd7658.tar.xz
eclipse.platform.team-0c99eae780ae585149301a910919c41ed1bd7658.zip
43249: [Team] JobStatusHandler and listeners
-rw-r--r--bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/TeamSubscriber.java23
-rw-r--r--bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/SubscriberManager.java26
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/JobStatusHandler.java66
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/sets/SyncSet.java20
4 files changed, 103 insertions, 32 deletions
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/TeamSubscriber.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/TeamSubscriber.java
index 44cc90f2c..9d9387813 100644
--- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/TeamSubscriber.java
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/TeamSubscriber.java
@@ -11,7 +11,6 @@
package org.eclipse.team.core.subscribers;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IResource;
@@ -19,7 +18,7 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.sync.IRemoteResource;
-import org.eclipse.team.internal.core.*;
+import org.eclipse.team.internal.core.SubscriberManager;
/**
* A TeamSubscriber provides synchronization between local resources and a remote location
@@ -240,8 +239,10 @@ abstract public class TeamSubscriber {
* @param listener a team resource change listener
*/
public void addListener(ITeamResourceChangeListener listener) {
- if(! listeners.contains(listener)) {
- listeners.add(listener);
+ synchronized (listeners) {
+ if(! listeners.contains(listener)) {
+ listeners.add(listener);
+ }
}
}
@@ -252,18 +253,24 @@ abstract public class TeamSubscriber {
* @param listener a team resource change listener
*/
public void removeListener(ITeamResourceChangeListener listener) {
- listeners.remove(listener);
+ synchronized (listeners) {
+ listeners.remove(listener);
+ }
}
/**
* Fires a team resource change event to all registered listeners
* Only listeners registered at the time this method is called are notified.
+ * Listener notification makes use of an ISafeRunnable to ensure that
+ * client exceptions do not effect the notification to other clients.
*/
protected void fireTeamResourceChange(final TeamDelta[] deltas) {
- for (Iterator it = listeners.iterator(); it.hasNext();) {
- final ITeamResourceChangeListener l = (ITeamResourceChangeListener) it.next();
- l.teamResourceChanged(deltas);
+ ITeamResourceChangeListener[] allListeners;
+ // Copy the listener list so we're not calling client code while synchronized
+ synchronized(listeners) {
+ allListeners = (ITeamResourceChangeListener[]) listeners.toArray(new ITeamResourceChangeListener[listeners.size()]);
}
+ ((SubscriberManager)getSubscriberManager()).fireTeamResourceChange(allListeners, deltas);
}
/**
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/SubscriberManager.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/SubscriberManager.java
index bd0f525e8..af9d95baa 100644
--- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/SubscriberManager.java
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/SubscriberManager.java
@@ -23,7 +23,9 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.subscribers.ISubscriberManager;
@@ -160,19 +162,31 @@ public class SubscriberManager implements ISubscriberManager, ISaveParticipant {
* Fires a team resource change event to all registered listeners
* Only listeners registered at the time this method is called are notified.
*/
- void fireTeamResourceChange(final TeamDelta[] deltas) {
+ protected void fireTeamResourceChange(TeamDelta[] deltas) {
ITeamResourceChangeListener[] allListeners;
// Copy the listener list so we're not calling client code while synchronized
synchronized(listeners) {
allListeners = (ITeamResourceChangeListener[]) listeners.toArray(new ITeamResourceChangeListener[listeners.size()]);
}
- // Fire the events
- for (int i = 0; i < allListeners.length; i++) {
- ITeamResourceChangeListener listener = allListeners[i];
- listener.teamResourceChanged(deltas);
- }
+ fireTeamResourceChange(allListeners, deltas);
}
+ public void fireTeamResourceChange(ITeamResourceChangeListener[] listeners, final TeamDelta[] deltas) {
+ // Notify the listeners safely so all will receive notification
+ for (int i = 0; i < listeners.length; i++) {
+ final ITeamResourceChangeListener listener = listeners[i];
+ Platform.run(new ISafeRunnable() {
+ public void handleException(Throwable exception) {
+ // don't log the exception....it is already being logged in Platform#run
+ }
+ public void run() throws Exception {
+ listener.teamResourceChanged(deltas);
+
+ }
+ });
+ }
+ }
+
synchronized void restoreSubscribers() {
try {
SaveContext root = SaveContextXMLWriter.readXMLPluginMetaFile(TeamPlugin.getPlugin(), "subscribers"); //$NON-NLS-1$
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/JobStatusHandler.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/JobStatusHandler.java
index 6803c05fc..1216e0022 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/JobStatusHandler.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/JobStatusHandler.java
@@ -17,6 +17,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
@@ -35,6 +37,30 @@ public class JobStatusHandler extends JobChangeAdapter {
private Set jobs = new HashSet();
private List listeners = new ArrayList();
+ /*
+ * Private class used to safely notify listeners of job type starts and
+ * finishes. Subclass override the notify(IJobListener) method to
+ * fire specific events inside an ISafeRunnable.
+ */
+ private abstract class Notification implements ISafeRunnable {
+ private IJobListener listener;
+ public void handleException(Throwable exception) {
+ // don't log the exception....it is already being logged in Platform#run
+ }
+ public void run(IJobListener listener) {
+ this.listener = listener;
+ Platform.run(this);
+ }
+ public void run() throws Exception {
+ notify(listener);
+ }
+ /**
+ * Subsclasses overide this method to send an event safely to a lsistener
+ * @param listener
+ */
+ protected abstract void notify(IJobListener listener);
+ }
+
/**
* Associate the job with the given jobType and schedule the job for
* immediate start.
@@ -146,10 +172,17 @@ public class JobStatusHandler extends JobChangeAdapter {
listeners.remove(listener);
}
}
-
- private IJobListener[] getJobListeners() {
+
+ private void fireNotification(Notification notification) {
+ // Get a snapshot of the listeners so the list doesn't change while we're firing
+ IJobListener[] listenerArray;
synchronized (listeners) {
- return (IJobListener[]) listeners.toArray(new IJobListener[listeners.size()]);
+ listenerArray = (IJobListener[]) listeners.toArray(new IJobListener[listeners.size()]);
+ }
+ // Notify each listener in a safe manner (i.e. so their exceptions don't kill us)
+ for (int i = 0; i < listenerArray.length; i++) {
+ IJobListener listener = listenerArray[i];
+ notification.run(listener);
}
}
@@ -182,11 +215,11 @@ public class JobStatusHandler extends JobChangeAdapter {
}
private void fireStartNotification() {
- IJobListener[] listenerArray = getJobListeners();
- for (int i = 0; i < listenerArray.length; i++) {
- IJobListener listener = listenerArray[i];
- listener.started(jobType);
- }
+ fireNotification(new Notification() {
+ public void notify(IJobListener listener) {
+ listener.started(getJobType());
+ }
+ });
}
private void jobDone(Job job) {
@@ -197,11 +230,11 @@ public class JobStatusHandler extends JobChangeAdapter {
}
private void fireEndNotification() {
- IJobListener[] listenerArray = getJobListeners();
- for (int i = 0; i < listenerArray.length; i++) {
- IJobListener listener = listenerArray[i];
- listener.finished(jobType);
- }
+ fireNotification(new Notification() {
+ public void notify(IJobListener listener) {
+ listener.finished(getJobType());
+ }
+ });
}
public boolean hasRunningJobs() {
@@ -214,4 +247,11 @@ public class JobStatusHandler extends JobChangeAdapter {
private boolean isEmpty() {
return listeners.isEmpty() && jobs.isEmpty();
}
+ /**
+ * @return Returns the jobType.
+ */
+ public QualifiedName getJobType() {
+ return jobType;
+ }
+
}
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/sets/SyncSet.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/sets/SyncSet.java
index 1dec633f4..e65080b1f 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/sets/SyncSet.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/sync/sets/SyncSet.java
@@ -23,8 +23,10 @@ import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
import org.eclipse.team.core.subscribers.SyncInfo;
import org.eclipse.team.internal.ui.TeamUIPlugin;
@@ -58,7 +60,7 @@ public class SyncSet {
private void fireChanges() {
// Use a synchronized block to ensure that the event we send is static
- SyncSetChangedEvent event;
+ final SyncSetChangedEvent event;
synchronized(this) {
event = changes;
resetChanges();
@@ -70,10 +72,18 @@ public class SyncSet {
synchronized(listeners) {
allListeners = (ISyncSetChangedListener[]) listeners.toArray(new ISyncSetChangedListener[listeners.size()]);
}
- // Fire the events
+ // Fire the events using an ISafeRunnable
for (int i = 0; i < allListeners.length; i++) {
- ISyncSetChangedListener listener = allListeners[i];
- listener.syncSetChanged(event);
+ final ISyncSetChangedListener listener = allListeners[i];
+ Platform.run(new ISafeRunnable() {
+ public void handleException(Throwable exception) {
+ // don't log the exception....it is already being logged in Platform#run
+ }
+ public void run() throws Exception {
+ listener.syncSetChanged(event);
+
+ }
+ });
}
}
@@ -243,7 +253,7 @@ public class SyncSet {
} else {
return new SyncInfo[] { info };
}
- };
+ }
IContainer container = (IContainer)resource;
IPath path = container.getFullPath();
Set children = (Set)parents.get(path);

Back to the top