aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemy Suen2011-07-14 12:29:12 (EDT)
committerPaul Webster2011-08-25 10:21:53 (EDT)
commitb8ab197ee3637cccb775fcfdba81f0ee91fdb687 (patch)
treebe0a43c809eb78ee13c5da76acc964e7f522f620
parent73dc602614b3f8772e154a1f914530d88ca74de4 (diff)
downloadeclipse.platform.ui-b8ab197ee3637cccb775fcfdba81f0ee91fdb687.zip
eclipse.platform.ui-b8ab197ee3637cccb775fcfdba81f0ee91fdb687.tar.gz
eclipse.platform.ui-b8ab197ee3637cccb775fcfdba81f0ee91fdb687.tar.bz2
Bug 352076 [Compatibility] Exception caused by having the 'XPath' view
open prevents Ctrl+W from operating Part listeners were not being notified safely so if an exception occurred in one of the listeners it would cause all other notifications to not occur. The fix then is to wrap notification calls within an ISafeRunnable so that every listener will get a chance to be notified even if another listener causes an exception.
-rw-r--r--bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java72
-rw-r--r--tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/tests/application/EPartServiceTest.java75
2 files changed, 131 insertions, 16 deletions
diff --git a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java
index 259ca54..2b842bb 100644
--- a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java
+++ b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java
@@ -19,7 +19,9 @@ import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Named;
import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.InjectionException;
@@ -182,33 +184,73 @@ public class PartServiceImpl implements EPartService {
partActivationHistory.clear();
}
- private void firePartActivated(MPart part) {
- for (Object listener : listeners.getListeners()) {
- ((IPartListener) listener).partActivated(part);
+ private void firePartActivated(final MPart part) {
+ for (final Object listener : listeners.getListeners()) {
+ SafeRunner.run(new ISafeRunnable() {
+ public void run() throws Exception {
+ ((IPartListener) listener).partActivated(part);
+ }
+
+ public void handleException(Throwable throwable) {
+ logger.error(throwable, "An exception occurred while notifying part listeners"); //$NON-NLS-1$
+ }
+ });
}
}
- private void firePartDeactivated(MPart part) {
- for (Object listener : listeners.getListeners()) {
- ((IPartListener) listener).partDeactivated(part);
+ private void firePartDeactivated(final MPart part) {
+ for (final Object listener : listeners.getListeners()) {
+ SafeRunner.run(new ISafeRunnable() {
+ public void run() throws Exception {
+ ((IPartListener) listener).partDeactivated(part);
+ }
+
+ public void handleException(Throwable throwable) {
+ logger.error(throwable, "An exception occurred while notifying part listeners"); //$NON-NLS-1$
+ }
+ });
}
}
- private void firePartHidden(MPart part) {
- for (Object listener : listeners.getListeners()) {
- ((IPartListener) listener).partHidden(part);
+ private void firePartHidden(final MPart part) {
+ for (final Object listener : listeners.getListeners()) {
+ SafeRunner.run(new ISafeRunnable() {
+ public void run() throws Exception {
+ ((IPartListener) listener).partHidden(part);
+ }
+
+ public void handleException(Throwable throwable) {
+ logger.error(throwable, "An exception occurred while notifying part listeners"); //$NON-NLS-1$
+ }
+ });
}
}
- private void firePartVisible(MPart part) {
- for (Object listener : listeners.getListeners()) {
- ((IPartListener) listener).partVisible(part);
+ private void firePartVisible(final MPart part) {
+ for (final Object listener : listeners.getListeners()) {
+ SafeRunner.run(new ISafeRunnable() {
+ public void run() throws Exception {
+ ((IPartListener) listener).partVisible(part);
+ }
+
+ public void handleException(Throwable throwable) {
+ logger.error(throwable, "An exception occurred while notifying part listeners"); //$NON-NLS-1$
+ }
+ });
}
}
- private void firePartBroughtToTop(MPart part) {
- for (Object listener : listeners.getListeners()) {
- ((IPartListener) listener).partBroughtToTop(part);
+ private void firePartBroughtToTop(final MPart part) {
+ for (final Object listener : listeners.getListeners()) {
+ SafeRunner.run(new ISafeRunnable() {
+ public void run() throws Exception {
+ ((IPartListener) listener).partBroughtToTop(part);
+ }
+
+ public void handleException(Throwable throwable) {
+ logger.error(throwable, "An exception occurred while notifying part listeners"); //$NON-NLS-1$
+ }
+ });
}
}
diff --git a/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/tests/application/EPartServiceTest.java b/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/tests/application/EPartServiceTest.java
index b3e9bd2..bd4e845 100644
--- a/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/tests/application/EPartServiceTest.java
+++ b/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/tests/application/EPartServiceTest.java
@@ -10464,6 +10464,45 @@ public class EPartServiceTest extends TestCase {
assertNull("The part should no longer be reachable", ref.get());
}
+ public void testsEventWithExceptions() {
+ MApplication application = ApplicationFactoryImpl.eINSTANCE
+ .createApplication();
+
+ MWindow window = BasicFactoryImpl.eINSTANCE.createWindow();
+ application.getChildren().add(window);
+ application.setSelectedElement(window);
+
+ MPartStack partStack = BasicFactoryImpl.eINSTANCE.createPartStack();
+ window.getChildren().add(partStack);
+ window.setSelectedElement(partStack);
+
+ MPart partA = BasicFactoryImpl.eINSTANCE.createPart();
+ window.getChildren().add(partA);
+ window.setSelectedElement(partA);
+
+ MPart partB = BasicFactoryImpl.eINSTANCE.createPart();
+ window.getChildren().add(partB);
+
+ initialize(applicationContext, application);
+ getEngine().createGui(window);
+
+ EPartService partService = window.getContext().get(EPartService.class);
+ partService.activate(partA);
+ partService.activate(partB);
+ partService.activate(partA);
+
+ partService.addPartListener(new ExceptionListener());
+ PartListener listener = new PartListener();
+ partService.addPartListener(listener);
+
+ partService.activate(partB);
+ assertEquals(1, listener.getActivated());
+ assertEquals(1, listener.getDeactivated());
+ assertEquals(1, listener.getVisible());
+ assertEquals(1, listener.getHidden());
+ assertEquals(1, listener.getBroughtToTop());
+ }
+
private MApplication createApplication(String partId) {
return createApplication(new String[] { partId });
}
@@ -10527,11 +10566,13 @@ public class EPartServiceTest extends TestCase {
private List<MPart> deactivatedParts = new ArrayList<MPart>();
private List<MPart> hiddenParts = new ArrayList<MPart>();
private List<MPart> visibleParts = new ArrayList<MPart>();
+ private List<MPart> broughtToTopParts = new ArrayList<MPart>();
private int activated = 0;
private int deactivated = 0;
private int hidden = 0;
private int visible = 0;
+ private int broughtToTop = 0;
private boolean valid = true;
@@ -10565,6 +10606,10 @@ public class EPartServiceTest extends TestCase {
return visible;
}
+ public int getBroughtToTop() {
+ return broughtToTop;
+ }
+
public boolean isValid() {
return valid;
}
@@ -10594,7 +10639,11 @@ public class EPartServiceTest extends TestCase {
}
public void partBroughtToTop(MPart part) {
-
+ if (valid && part == null) {
+ valid = false;
+ }
+ broughtToTop++;
+ broughtToTopParts.add(part);
}
public void partDeactivated(MPart part) {
@@ -10622,4 +10671,28 @@ public class EPartServiceTest extends TestCase {
}
}
+
+ class ExceptionListener implements IPartListener {
+
+ public void partActivated(MPart part) {
+ throw new RuntimeException();
+ }
+
+ public void partBroughtToTop(MPart part) {
+ throw new RuntimeException();
+ }
+
+ public void partDeactivated(MPart part) {
+ throw new RuntimeException();
+ }
+
+ public void partHidden(MPart part) {
+ throw new RuntimeException();
+ }
+
+ public void partVisible(MPart part) {
+ throw new RuntimeException();
+ }
+
+ }
}