From 33a464d16b742c890ed251d714f8ca6f3f8cd8e6 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Thu, 5 Jul 2012 21:18:35 +1000 Subject: NEW - bug 384255: Alert ContextContributor about contextActivated/contextDeactivated events https://bugs.eclipse.org/bugs/show_bug.cgi?id=384255 Change-Id: I5bd2a12a3a433e3c3a428a587553bf3e96098f81 --- .../context/core/AbstractContextListener.java | 2 +- .../mylyn/context/core/IContextContributor.java | 2 +- .../mylyn/context/core/IContextListener.java | 31 +++++++++++ .../context/core/IInteractionContextManager.java | 10 ++++ .../internal/context/core/ContextCorePlugin.java | 7 ++- .../context/core/InteractionContextManager.java | 63 +++++++++++++--------- .../eclipse/mylyn/ide/tests/IdeStartupTest.java | 6 +-- 7 files changed, 90 insertions(+), 31 deletions(-) create mode 100644 org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/context/core/IContextListener.java diff --git a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/context/core/AbstractContextListener.java b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/context/core/AbstractContextListener.java index 24b5de20f..215612240 100644 --- a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/context/core/AbstractContextListener.java +++ b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/context/core/AbstractContextListener.java @@ -25,7 +25,7 @@ import org.eclipse.mylyn.internal.context.core.ContextCorePlugin; * @author Shawn Minto * @since 3.0 */ -public abstract class AbstractContextListener { +public abstract class AbstractContextListener implements IContextListener { /** * Invoked before the context is activated. diff --git a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/context/core/IContextContributor.java b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/context/core/IContextContributor.java index 05fb7a1ce..bf2f1dbda 100644 --- a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/context/core/IContextContributor.java +++ b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/context/core/IContextContributor.java @@ -21,7 +21,7 @@ import java.io.InputStream; * @noextend This interface is not intended to be extended by clients. * @noimplement This interface is not intended to be implemented by clients. */ -public interface IContextContributor { +public interface IContextContributor extends IContextListener { /** * Provides data which should be added to the given context. diff --git a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/context/core/IContextListener.java b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/context/core/IContextListener.java new file mode 100644 index 000000000..7694e4b4c --- /dev/null +++ b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/context/core/IContextListener.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2012 Sebastian Schmidt and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sebastian Schmidt - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.context.core; + +/** + * Interface to be notified of context change events. + * + * @since 3.9 + * @author Sebastian Schmidt + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IContextListener { + + /** + * Context state changed + * + * @param ContextChangeEvent + * event containing the change details + */ + public void contextChanged(ContextChangeEvent event); + +} diff --git a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/context/core/IInteractionContextManager.java b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/context/core/IInteractionContextManager.java index 6ff14b2b5..84b4ebabf 100644 --- a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/context/core/IInteractionContextManager.java +++ b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/context/core/IInteractionContextManager.java @@ -29,6 +29,16 @@ public interface IInteractionContextManager { */ public abstract IInteractionElement getElement(String elementHandle); + /** + * @since 3.9 + */ + public abstract void addListener(IContextListener listener); + + /** + * @since 3.9 + */ + public abstract void removeListener(IContextListener listener); + public abstract void addListener(AbstractContextListener listener); public abstract void removeListener(AbstractContextListener listener); diff --git a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/context/core/ContextCorePlugin.java b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/context/core/ContextCorePlugin.java index ce46d9ff2..c7f3013f9 100644 --- a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/context/core/ContextCorePlugin.java +++ b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/context/core/ContextCorePlugin.java @@ -227,23 +227,28 @@ public class ContextCorePlugin extends Plugin { return contextContributor; } - private void initContextContributor() { + void initContextContributor() { if (!contextContributorInitialized) { ExtensionPointReader extensionPointReader = new ExtensionPointReader( ContextCorePlugin.ID_PLUGIN, ContextCorePlugin.EXTENSION_ID_CONTRIBUTOR, ContextCorePlugin.EXTENSION_ELEMENT_CONTRIBUTOR, IContextContributor.class); extensionPointReader.read(); contextContributor = extensionPointReader.getItems(); + for (IContextContributor contributor : contextContributor) { + ContextCorePlugin.getContextManager().addListener(contributor); + } contextContributorInitialized = true; } } public void addContextContributor(AbstractContextContributor contributor) { contextContributor.add(contributor); + ContextCorePlugin.getContextManager().addListener(contributor); } public void removeContextContributor(AbstractContextContributor contributor) { contextContributor.remove(contributor); + ContextCorePlugin.getContextManager().removeListener(contributor); } /** diff --git a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/context/core/InteractionContextManager.java b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/context/core/InteractionContextManager.java index 1505bab15..631138699 100644 --- a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/context/core/InteractionContextManager.java +++ b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/context/core/InteractionContextManager.java @@ -43,6 +43,7 @@ import org.eclipse.mylyn.context.core.AbstractContextStructureBridge; import org.eclipse.mylyn.context.core.ContextChangeEvent; import org.eclipse.mylyn.context.core.ContextChangeEvent.ContextChangeKind; import org.eclipse.mylyn.context.core.ContextCore; +import org.eclipse.mylyn.context.core.IContextListener; import org.eclipse.mylyn.context.core.IInteractionContext; import org.eclipse.mylyn.context.core.IInteractionContextManager; import org.eclipse.mylyn.context.core.IInteractionElement; @@ -127,11 +128,11 @@ public class InteractionContextManager implements IInteractionContextManager { private InteractionContext activityMetaContext = null; - private final List activityMetaContextListeners = new CopyOnWriteArrayList(); + private final List activityMetaContextListeners = new CopyOnWriteArrayList(); private boolean contextCapturePaused = false; - private final List contextListeners = new CopyOnWriteArrayList(); + private final List contextListeners = new CopyOnWriteArrayList(); private final List errorElementHandles = new ArrayList(); @@ -145,7 +146,7 @@ public class InteractionContextManager implements IInteractionContextManager { private boolean suppressListenerNotification = false; - private final List waitingContextListeners = new ArrayList(); + private final List waitingContextListeners = new ArrayList(); private final LocalContextStore contextStore; @@ -163,7 +164,9 @@ public class InteractionContextManager implements IInteractionContextManager { context = loadedContext; } - for (final AbstractContextListener listener : contextListeners) { + // make sure contextContributor are initialized + ContextCorePlugin.getDefault().initContextContributor(); + for (final IContextListener listener : contextListeners) { SafeRunner.run(new ISafeRunnable() { public void handleException(Throwable e) { StatusHandler.log(new Status(IStatus.WARNING, ContextCorePlugin.ID_PLUGIN, "Listener failed: " //$NON-NLS-1$ @@ -249,6 +252,10 @@ public class InteractionContextManager implements IInteractionContextManager { } public void addListener(AbstractContextListener listener) { + addListener((IContextListener) listener); + } + + public void addListener(IContextListener listener) { Assert.isNotNull(listener); if (suppressListenerNotification && !waitingContextListeners.contains(listener)) { waitingContextListeners.add(listener); @@ -273,7 +280,7 @@ public class InteractionContextManager implements IInteractionContextManager { if (bridge.canBeLandmark(node.getHandleIdentifier())) { if (previousInterest >= ContextCore.getCommonContextScaling().getLandmark() && !node.getInterest().isLandmark()) { - for (final AbstractContextListener listener : contextListeners) { + for (final IContextListener listener : contextListeners) { SafeRunner.run(new ISafeRunnable() { public void handleException(Throwable e) { StatusHandler.log(new Status(IStatus.WARNING, ContextCorePlugin.ID_PLUGIN, @@ -292,7 +299,7 @@ public class InteractionContextManager implements IInteractionContextManager { } } else if (previousInterest < ContextCore.getCommonContextScaling().getLandmark() && node.getInterest().isLandmark()) { - for (final AbstractContextListener listener : contextListeners) { + for (final IContextListener listener : contextListeners) { SafeRunner.run(new ISafeRunnable() { public void handleException(Throwable e) { StatusHandler.log(new Status(IStatus.WARNING, ContextCorePlugin.ID_PLUGIN, @@ -443,7 +450,7 @@ public class InteractionContextManager implements IInteractionContextManager { activeContext.getContextMap().remove(handleIdentifier); setContextCapturePaused(true); - for (final AbstractContextListener listener : contextListeners) { + for (final IContextListener listener : contextListeners) { SafeRunner.run(new ISafeRunnable() { public void handleException(Throwable e) { StatusHandler.log(new Status(IStatus.WARNING, ContextCorePlugin.ID_PLUGIN, @@ -507,7 +514,7 @@ public class InteractionContextManager implements IInteractionContextManager { eraseContext(handleIdentifier); contextStore.deleteContext(handleIdentifier); - for (final AbstractContextListener listener : contextListeners) { + for (final IContextListener listener : contextListeners) { SafeRunner.run(new ISafeRunnable() { public void handleException(Throwable e) { StatusHandler.log(new Status(IStatus.WARNING, ContextCorePlugin.ID_PLUGIN, "Listener failed: " //$NON-NLS-1$ @@ -651,7 +658,7 @@ public class InteractionContextManager implements IInteractionContextManager { /** * For testing. */ - public List getListeners() { + public List getListeners() { return Collections.unmodifiableList(contextListeners); } @@ -688,7 +695,7 @@ public class InteractionContextManager implements IInteractionContextManager { InteractionContextManager.ACTIVITY_DELTA_ACTIVATED, 1f)); } - for (final AbstractContextListener listener : contextListeners) { + for (final IContextListener listener : contextListeners) { SafeRunner.run(new ISafeRunnable() { public void handleException(Throwable e) { StatusHandler.log(new Status(IStatus.WARNING, ContextCorePlugin.ID_PLUGIN, "Listener failed: " //$NON-NLS-1$ @@ -789,7 +796,7 @@ public class InteractionContextManager implements IInteractionContextManager { public void loadActivityMetaContext() { if (contextStore != null) { - for (final AbstractContextListener listener : activityMetaContextListeners) { + for (final IContextListener listener : activityMetaContextListeners) { SafeRunner.run(new ISafeRunnable() { public void handleException(Throwable e) { StatusHandler.log(new Status(IStatus.WARNING, ContextCorePlugin.ID_PLUGIN, "Listener failed: " //$NON-NLS-1$ @@ -829,7 +836,7 @@ public class InteractionContextManager implements IInteractionContextManager { metaContextLock.release(); } - for (final AbstractContextListener listener : activityMetaContextListeners) { + for (final IContextListener listener : activityMetaContextListeners) { SafeRunner.run(new ISafeRunnable() { public void handleException(Throwable e) { StatusHandler.log(new Status(IStatus.WARNING, ContextCorePlugin.ID_PLUGIN, "Listener failed: " //$NON-NLS-1$ @@ -1085,7 +1092,7 @@ public class InteractionContextManager implements IInteractionContextManager { private void notifyElementsDeleted(final IInteractionContext context, final List interestDelta, final boolean isExplicitManipulation) { if (!interestDelta.isEmpty()) { - for (final AbstractContextListener listener : contextListeners) { + for (final IContextListener listener : contextListeners) { SafeRunner.run(new ISafeRunnable() { public void handleException(Throwable e) { StatusHandler.log(new Status(IStatus.WARNING, ContextCorePlugin.ID_PLUGIN, "Listener failed: " //$NON-NLS-1$ @@ -1109,7 +1116,7 @@ public class InteractionContextManager implements IInteractionContextManager { public void notifyInterestDelta(final IInteractionContext context, final List interestDelta) { if (!interestDelta.isEmpty()) { - for (final AbstractContextListener listener : contextListeners) { + for (final IContextListener listener : contextListeners) { SafeRunner.run(new ISafeRunnable() { public void handleException(Throwable e) { StatusHandler.log(new Status(IStatus.WARNING, ContextCorePlugin.ID_PLUGIN, "Listener failed: " //$NON-NLS-1$ @@ -1135,7 +1142,7 @@ public class InteractionContextManager implements IInteractionContextManager { if (suppressListenerNotification) { return; } - for (final AbstractContextListener listener : contextListeners) { + for (final IContextListener listener : contextListeners) { if (listener instanceof IRelationsListener) { SafeRunner.run(new ISafeRunnable() { public void handleException(Throwable e) { @@ -1156,7 +1163,7 @@ public class InteractionContextManager implements IInteractionContextManager { IInteractionElement element = getActivityMetaContext().parseEvent(event); final List changed = Collections.singletonList(element); - for (final AbstractContextListener listener : activityMetaContextListeners) { + for (final IContextListener listener : activityMetaContextListeners) { SafeRunner.run(new ISafeRunnable() { public void handleException(Throwable e) { StatusHandler.log(new Status(IStatus.WARNING, ContextCorePlugin.ID_PLUGIN, "Listener failed: " //$NON-NLS-1$ @@ -1394,7 +1401,7 @@ public class InteractionContextManager implements IInteractionContextManager { * TODO: worry about decay-related change if predicted interest dacays */ @SuppressWarnings("deprecation") - public void removeErrorPredictedInterest(String handle, String kind, boolean notify) { + public void removeErrorPredictedInterest(final String handle, String kind, boolean notify) { if (activeContext.getContextMap().isEmpty()) { return; } @@ -1411,7 +1418,12 @@ public class InteractionContextManager implements IInteractionContextManager { errorElementHandles.remove(handle); // TODO: this results in double-notification if (notify) { - for (final AbstractContextListener listener : contextListeners) { + List changed = new ArrayList(); + changed.add(element); + final ContextChangeEvent contextChangeEvent = new ContextChangeEvent( + ContextChangeKind.INTEREST_CHANGED, handle, null, changed); + + for (final IContextListener listener : contextListeners) { SafeRunner.run(new ISafeRunnable() { public void handleException(Throwable e) { StatusHandler.log(new Status(IStatus.WARNING, ContextCorePlugin.ID_PLUGIN, @@ -1420,10 +1432,7 @@ public class InteractionContextManager implements IInteractionContextManager { } public void run() throws Exception { - // FIXME use singleton list instead that is constructed outside of loop - List changed = new ArrayList(); - changed.add(element); - listener.interestChanged(changed); + listener.contextChanged(contextChangeEvent); } }); } @@ -1436,6 +1445,10 @@ public class InteractionContextManager implements IInteractionContextManager { } public void removeListener(AbstractContextListener listener) { + removeListener((IContextListener) listener); + } + + public void removeListener(IContextListener listener) { waitingContextListeners.remove(listener); contextListeners.remove(listener); } @@ -1459,7 +1472,7 @@ public class InteractionContextManager implements IInteractionContextManager { } } } - for (final AbstractContextListener listener : contextListeners) { + for (final IContextListener listener : contextListeners) { if (listener instanceof IRelationsListener) { SafeRunner.run(new ISafeRunnable() { public void handleException(Throwable e) { @@ -1502,7 +1515,7 @@ public class InteractionContextManager implements IInteractionContextManager { context.updateElementHandle(element, newHandle); final List changed = Collections.singletonList(element); - for (final AbstractContextListener listener : contextListeners) { + for (final IContextListener listener : contextListeners) { SafeRunner.run(new ISafeRunnable() { public void handleException(Throwable e) { StatusHandler.log(new Status(IStatus.WARNING, ContextCorePlugin.ID_PLUGIN, "Listener failed: " //$NON-NLS-1$ @@ -1517,7 +1530,7 @@ public class InteractionContextManager implements IInteractionContextManager { }); } if (element.getInterest().isLandmark()) { - for (final AbstractContextListener listener : contextListeners) { + for (final IContextListener listener : contextListeners) { SafeRunner.run(new ISafeRunnable() { public void handleException(Throwable e) { StatusHandler.log(new Status(IStatus.WARNING, ContextCorePlugin.ID_PLUGIN, "Listener failed: " //$NON-NLS-1$ diff --git a/org.eclipse.mylyn.ide.tests/src/org/eclipse/mylyn/ide/tests/IdeStartupTest.java b/org.eclipse.mylyn.ide.tests/src/org/eclipse/mylyn/ide/tests/IdeStartupTest.java index 81f458b6c..e2ce6e67a 100644 --- a/org.eclipse.mylyn.ide.tests/src/org/eclipse/mylyn/ide/tests/IdeStartupTest.java +++ b/org.eclipse.mylyn.ide.tests/src/org/eclipse/mylyn/ide/tests/IdeStartupTest.java @@ -15,7 +15,7 @@ import java.util.List; import junit.framework.TestCase; -import org.eclipse.mylyn.context.core.AbstractContextListener; +import org.eclipse.mylyn.context.core.IContextListener; import org.eclipse.mylyn.context.sdk.util.ContextTestUtil; import org.eclipse.mylyn.internal.context.core.ContextCorePlugin; import org.eclipse.mylyn.internal.team.ui.ContextActiveChangeSetManager; @@ -31,9 +31,9 @@ public class IdeStartupTest extends TestCase { } public void testChangeSetsStartup() { - List listeners = ContextCorePlugin.getContextManager().getListeners(); + List listeners = ContextCorePlugin.getContextManager().getListeners(); boolean containsManager = false; - for (AbstractContextListener listener : listeners) { + for (IContextListener listener : listeners) { if (listener instanceof ContextActiveChangeSetManager) { containsManager = true; } -- cgit v1.2.3