diff options
author | John Arthorne | 2009-06-30 17:24:11 +0000 |
---|---|---|
committer | John Arthorne | 2009-06-30 17:24:11 +0000 |
commit | 3b63a025b99a5f04cb21e581f1d1991768d93a9e (patch) | |
tree | ce5fdbd8396893e0c2d41c99b82e4ae7a04f9314 | |
parent | 99ea405152d8f345be3006dc71d7c142d4cbeebf (diff) | |
download | eclipse.platform.runtime-20090630-1500.tar.gz eclipse.platform.runtime-20090630-1500.tar.xz eclipse.platform.runtime-20090630-1500.zip |
Bug 281890 Encapsulate IRunAndTrack#notify parametersv20090630-1500
10 files changed, 219 insertions, 108 deletions
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/ContextEvent.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/ContextEvent.java new file mode 100644 index 000000000..7c955eafc --- /dev/null +++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/ContextEvent.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2009 IBM Corporation 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.core.services.context; + +/** + * An event describing a change to an {@link IEclipseContext}. The following types of events are + * currently defined: + * <ul> + * <li>An event indicating that the listener has just been registered with a context.</li> + * <li>An after-the-fact report that a context value has been changed (either a new value or a + * change to an existing value.</li> + * <li>An after-the-fact report that a context value has been removed.</li> + * <li>A report that a context is about to be disposed.</li> + * </ul> + * <p> + * In order to handle additional event types that may be introduced in future releases, clients + * should not write code that presumes the set of event types is closed. + * </p> + * + * @see IRunAndTrack + */ +public final class ContextEvent { + /** + * A change event type (value "0"), indicating that the listener receiving this event has just + * been registered with a context. + * + * @see IEclipseContext#runAndTrack(IRunAndTrack, Object[]) + */ + public static final int INITIAL = 0; + + /** + * A change event type (value "1"), indicating that a context value has been added. + */ + public static final int ADDED = 1; + + /** + * A change event type (value "2"), indicating that a context value has been removed. + */ + public static final int REMOVED = 2; + + /** + * A change event type (value "3") indicating that the context is being disposed. The context is + * still valid at the time of this event. + */ + public static final int DISPOSE = 3; + + private Object[] args; + private IEclipseContext context; + private int eventType; + private String key; + + /** + * Creates a new context event. + * + * @param context + * @param key + * @param eventType + * @param args + */ + ContextEvent(IEclipseContext context, String key, int eventType, Object[] args) { + this.context = context; + this.key = key; + this.eventType = eventType; + this.args = args; + } + + /** + * Returns the arguments that were supplied when the listener was registered. + * + * @see IEclipseContext#runAndTrack(IRunAndTrack, Object[]) + * @return the arguments that were supplied when the listener was registered. + */ + public Object[] getArguments() { + return args; + } + + /** + * Returns the context where the change occurred. + * + * @return the context where the change occurred + */ + public IEclipseContext getContext() { + return context; + } + + /** + * Returns the type of content change that occurred. + * + * @return the type of content change that occurred. + */ + public int getEventType() { + return eventType; + } + + /** + * Returns the name of the context value that changed, or <code>null</code> if not applicable if + * this event type. + * + * @return The name of the changed context value, or <code>null</code> + */ + public String getName() { + return key; + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/EclipseContextFactory.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/EclipseContextFactory.java index a13319409..71ba78f8a 100644 --- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/EclipseContextFactory.java +++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/EclipseContextFactory.java @@ -62,4 +62,27 @@ public final class EclipseContextFactory { "OSGi context for bundle: " + bundleContext.getBundle().getSymbolicName()); //$NON-NLS-1$ return result; } + + /** + * Creates a new context change event. + * + * @noreference This method is not intended to be referenced by clients. + * @param context + * The context in which the event occurred + * @param eventType + * The type of change that occurred + * @param args + * The arguments that were supplied when the context listener was registered + * @param name + * The name of the context value that changed + * @param oldValue + * The value associated with the changed name before the change occurred. Return + * <code>null</code> if there was no previous value, or if not applicable for this + * type of event. + * @return A new context change event + */ + public static ContextEvent createContextEvent(IEclipseContext context, int eventType, + Object[] args, String name, Object oldValue) { + return new ContextEvent(context, name, eventType, args); + } }
\ No newline at end of file diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/IEclipseContext.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/IEclipseContext.java index 801b32a12..f1036810c 100644 --- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/IEclipseContext.java +++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/IEclipseContext.java @@ -12,7 +12,6 @@ package org.eclipse.e4.core.services.context; import org.eclipse.e4.core.services.context.spi.ContextFunction; -import org.eclipse.e4.core.services.context.spi.IRunAndTrack; /** * A context is used to isolate application code from its dependencies on an diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/IRunAndTrack.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/IRunAndTrack.java new file mode 100644 index 000000000..99360949c --- /dev/null +++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/IRunAndTrack.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2009 IBM Corporation 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: + * IBM Corporation - initial API and implementation + ******************************************************************************/ +package org.eclipse.e4.core.services.context; + +/** + * Extended version of a runnable that can be used with the + * {@link IEclipseContext#runAndTrack(IRunAndTrack, Object[])} version gets more detailed + * information on the change, such as the service name and the event type. + */ +public interface IRunAndTrack { + + /** + * Executes this runnable. The reason for the execution is provided in the + * <code>eventType</code> argument. + * + * @param event + * The event that occurred + */ + public boolean notify(ContextEvent event); +} diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/spi/IRunAndTrack.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/spi/IRunAndTrack.java deleted file mode 100644 index e208e2821..000000000 --- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/spi/IRunAndTrack.java +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 IBM Corporation 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: - * IBM Corporation - initial API and implementation - ******************************************************************************/ -package org.eclipse.e4.core.services.context.spi; - -import org.eclipse.e4.core.services.context.IEclipseContext; - -/** - * Extended version of a runnable that can be used with the - * {@link IEclipseContext#runAndTrack(IRunAndTrack, Object[])} version gets more - * detailed information on the change, such as the service name and the event - * type. - */ -public interface IRunAndTrack { - - /** - * A change event type (value "0"), indicating that this runnable has just - * been registered with a context. - * - * @see IEclipseContext#runAndTrack(IRunAndTrack, Object[]) - */ - public int INITIAL = 0; - - /** - * A change event type (value "1"), indicating that a context value has been - * added. - */ - public int ADDED = 1; - - /** - * A change event type (value "2"), indicating that a context value has been - * removed. - */ - public int REMOVED = 2; - - /** - * A change event type (value "3") indicating that the context is being - * disposed. - */ - public int DISPOSE = 3; - - /** - * Executes this runnable. The reason for the execution is provided in the - * <code>eventType</code> argument. - * - * @param context - * The context that triggered this notification - * @param name - * name of the context value that changed - * @param eventType - * describes the type of change, one of {@link #INITIAL}, - * {@link #ADDED}, {@link #REMOVED}, or {@link #DISPOSE} - * @param args - * The arguments that were supplied when this runnable was - * registered with the context - */ - public boolean notify(IEclipseContext context, String name, int eventType, Object[] args); -} diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/spi/ISchedulerStrategy.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/spi/ISchedulerStrategy.java index 5d45af570..b70028a1a 100644 --- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/spi/ISchedulerStrategy.java +++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/spi/ISchedulerStrategy.java @@ -11,6 +11,8 @@ package org.eclipse.e4.core.services.context.spi; +import org.eclipse.e4.core.services.context.IRunAndTrack; + import org.eclipse.e4.core.services.context.IEclipseContext; /** diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/Computation.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/Computation.java index 16dc7aa4d..e98791bba 100644 --- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/Computation.java +++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/Computation.java @@ -10,13 +10,14 @@ *******************************************************************************/ package org.eclipse.e4.core.services.internal.context; +import org.eclipse.e4.core.services.context.ContextEvent; + import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.eclipse.e4.core.services.context.IEclipseContext; -import org.eclipse.e4.core.services.context.spi.IRunAndTrack; abstract class Computation { Map dependencies = new HashMap(); @@ -48,7 +49,7 @@ abstract class Computation { final void handleInvalid(IEclipseContext context, String name, int eventType) { Set names = (Set) dependencies.get(context); - if (name == null && eventType == IRunAndTrack.DISPOSE) { + if (name == null && eventType == ContextEvent.DISPOSE) { clear(context, null); doHandleInvalid(context, null, eventType); } else if (names != null && names.contains(name)) { diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ContextToObjectLink.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ContextToObjectLink.java index 8a0ff3f58..d54e5f30f 100644 --- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ContextToObjectLink.java +++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ContextToObjectLink.java @@ -10,6 +10,9 @@ *******************************************************************************/ package org.eclipse.e4.core.services.internal.context; +import org.eclipse.e4.core.services.context.ContextEvent; +import org.eclipse.e4.core.services.context.IRunAndTrack; + import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.lang.ref.WeakReference; @@ -24,7 +27,6 @@ import java.util.Set; import org.eclipse.e4.core.services.context.IEclipseContext; import org.eclipse.e4.core.services.context.spi.ContextInjectionFactory; import org.eclipse.e4.core.services.context.spi.IContextConstants; -import org.eclipse.e4.core.services.context.spi.IRunAndTrack; /** * Implements injection of context values into an object. Tracks context changes and makes the @@ -89,9 +91,9 @@ public class ContextToObjectLink implements IRunAndTrack, IContextConstants { fieldPrefixLength = this.fieldPrefix.length(); } - public boolean notify(final IEclipseContext notifyContext, final String name, - final int eventType, final Object[] args) { - if (eventType == IRunAndTrack.DISPOSE) { + public boolean notify(final ContextEvent event) { + final String name = event.getName(); + if (event.getEventType() == ContextEvent.DISPOSE) { for (Iterator it = userObjects.iterator(); it.hasNext();) { WeakReference ref = (WeakReference) it.next(); Object referent = ref.get(); @@ -99,14 +101,14 @@ public class ContextToObjectLink implements IRunAndTrack, IContextConstants { findAndCallDispose(referent, referent.getClass(), new ProcessMethodsResult()); } } - boolean isSetter = (eventType == IRunAndTrack.ADDED || eventType == IRunAndTrack.INITIAL); + boolean isSetter = (event.getEventType() == ContextEvent.ADDED || event.getEventType() == ContextEvent.INITIAL); Processor processor = new Processor(isSetter) { void processField(final Field field, String injectName, boolean optional) { - switch (eventType) { - case IRunAndTrack.INITIAL: + switch (event.getEventType()) { + case ContextEvent.INITIAL: String key = findKey(injectName, field.getType()); if (key != null) { - setField(args[0], field, notifyContext.get(key)); + setField(event.getArguments()[0], field, event.getContext().get(key)); } else { if (!optional) { throw new IllegalStateException("Could not set " + field @@ -114,22 +116,22 @@ public class ContextToObjectLink implements IRunAndTrack, IContextConstants { } } break; - case IRunAndTrack.ADDED: + case ContextEvent.ADDED: String injectKey = findKey(name, field.getType()); if (injectKey != null && (keyMatches(name, injectName) || field.getType().getName().equals( name))) - setField(userObject, field, notifyContext.get(injectKey)); + setField(userObject, field, event.getContext().get(injectKey)); break; - case IRunAndTrack.REMOVED: + case ContextEvent.REMOVED: if (keyMatches(name, injectName) || field.getType().getName().equals(name)) setField(userObject, field, null); break; - case IRunAndTrack.DISPOSE: + case ContextEvent.DISPOSE: break; default: logWarning(userObject, new IllegalArgumentException("Unknown event type: " - + eventType)); + + event.getEventType())); } } @@ -142,12 +144,12 @@ public class ContextToObjectLink implements IRunAndTrack, IContextConstants { // only inject methods with a single parameter if (parameterTypes.length != 1) return; - switch (eventType) { - case IRunAndTrack.INITIAL: + switch (event.getEventType()) { + case ContextEvent.INITIAL: // when initializing, inject every method that has a match in the context String key = findKey(candidateName, parameterTypes[0]); if (key != null) { - setMethod(userObject, method, notifyContext.get(key, parameterTypes)); + setMethod(userObject, method, event.getContext().get(key, parameterTypes)); } else { if (!optional) { throw new IllegalStateException("Could not invoke " + method @@ -155,27 +157,27 @@ public class ContextToObjectLink implements IRunAndTrack, IContextConstants { } } break; - case IRunAndTrack.ADDED: + case ContextEvent.ADDED: // on add event, only inject the method corresponding to the added context key if (keyMatches(name, candidateName)) { key = findKey(name, parameterTypes[0]); - setMethod(userObject, method, notifyContext.get(key, parameterTypes)); + setMethod(userObject, method, event.getContext().get(key, parameterTypes)); } break; - case IRunAndTrack.REMOVED: + case ContextEvent.REMOVED: if (keyMatches(name, candidateName)) setMethod(userObject, method, null); break; - case IRunAndTrack.DISPOSE: + case ContextEvent.DISPOSE: break; default: logWarning(userObject, new IllegalArgumentException("Unknown event type: " - + eventType)); + + event.getEventType())); } } void processPostConstructMethod(Method m) { - if (eventType == IRunAndTrack.INITIAL) { + if (event.getEventType() == ContextEvent.INITIAL) { Object[] methodArgs = null; if (m.getParameterTypes().length == 1) methodArgs = new Object[] { context }; @@ -197,8 +199,9 @@ public class ContextToObjectLink implements IRunAndTrack, IContextConstants { } public void processOutMethod(Method m, final String name) { - final EclipseContext outputContext = (EclipseContext) notifyContext.get("outputs"); - if (eventType == IRunAndTrack.INITIAL) { + final EclipseContext outputContext = (EclipseContext) event.getContext().get( + "outputs"); + if (event.getEventType() == ContextEvent.INITIAL) { if (outputContext == null) { throw new IllegalStateException("No output context available for @Out " + m + " in " + userObject); @@ -221,7 +224,7 @@ public class ContextToObjectLink implements IRunAndTrack, IContextConstants { outputContext.set(name, value); } }); - + Method addListener = userObject.getClass().getMethod( "addPropertyChangeListener", new Class[] { String.class, PropertyChangeListener.class }); @@ -233,10 +236,11 @@ public class ContextToObjectLink implements IRunAndTrack, IContextConstants { } } }; - if (eventType == IRunAndTrack.INITIAL) { - if (args == null || args.length == 0 || args[0] == null) + if (event.getEventType() == ContextEvent.INITIAL) { + if (event.getArguments() == null || event.getArguments().length == 0 + || event.getArguments()[0] == null) throw new IllegalArgumentException(); - Object userObject = args[0]; + Object userObject = event.getArguments()[0]; processor.setObject(userObject); processClassHierarchy(userObject.getClass(), processor); diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/EclipseContext.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/EclipseContext.java index e370379d0..49c8c702c 100644 --- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/EclipseContext.java +++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/EclipseContext.java @@ -10,6 +10,11 @@ *******************************************************************************/ package org.eclipse.e4.core.services.internal.context; +import org.eclipse.e4.core.services.context.EclipseContextFactory; + +import org.eclipse.e4.core.services.context.ContextEvent; +import org.eclipse.e4.core.services.context.IRunAndTrack; + import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -24,7 +29,6 @@ import org.eclipse.e4.core.services.context.IEclipseContext; import org.eclipse.e4.core.services.context.spi.IContextConstants; import org.eclipse.e4.core.services.context.spi.IEclipseContextStrategy; import org.eclipse.e4.core.services.context.spi.ILookupStrategy; -import org.eclipse.e4.core.services.context.spi.IRunAndTrack; import org.eclipse.e4.core.services.context.spi.ISchedulerStrategy; public class EclipseContext implements IEclipseContext, IDisposable { @@ -116,7 +120,7 @@ public class EclipseContext implements IEclipseContext, IDisposable { } final protected void doHandleInvalid(IEclipseContext context, String name, int eventType) { - if (eventType == IRunAndTrack.DISPOSE) { + if (eventType == ContextEvent.DISPOSE) { return; } if (EclipseContext.DEBUG) @@ -184,12 +188,14 @@ public class EclipseContext implements IEclipseContext, IDisposable { // IEclipseContext } - public boolean notify(IEclipseContext context, String name, int eventType, Object[] args) { + public boolean notify(ContextEvent event) { Computation oldComputation = (Computation) currentComputation.get(); currentComputation.set(this); boolean result = true; try { - result = runnable.notify(context, name, eventType, args); + result = runnable.notify(EclipseContextFactory + .createContextEvent(event.getContext(), event.getEventType(), event + .getArguments(), event.getName(), null)); } finally { currentComputation.set(oldComputation); } @@ -247,7 +253,7 @@ public class EclipseContext implements IEclipseContext, IDisposable { public void dispose() { Computation[] ls = (Computation[]) listeners.toArray(new Computation[listeners.size()]); for (int i = 0; i < ls.length; i++) { - ls[i].handleInvalid(this, null, IRunAndTrack.DISPOSE); + ls[i].handleInvalid(this, null, ContextEvent.DISPOSE); } if (strategy instanceof IDisposable) ((IDisposable) strategy).dispose(); @@ -328,7 +334,7 @@ public class EclipseContext implements IEclipseContext, IDisposable { public void remove(String name) { if (isSetLocally(name)) { localValues.remove(name); - invalidate(name, IRunAndTrack.REMOVED); + invalidate(name, ContextEvent.REMOVED); } } @@ -356,7 +362,7 @@ public class EclipseContext implements IEclipseContext, IDisposable { public void runAndTrack(final IRunAndTrack runnable, Object[] args) { TrackableComputationExt computation = new TrackableComputationExt(runnable); - schedule(computation, null, IRunAndTrack.INITIAL, args); + schedule(computation, null, ContextEvent.INITIAL, args); } public void runAndTrack(final Runnable runnable) { @@ -367,10 +373,10 @@ public class EclipseContext implements IEclipseContext, IDisposable { protected boolean schedule(IRunAndTrack runnable, String name, int eventType, Object[] args) { if (runnable == null) return false; - if (eventType != IRunAndTrack.INITIAL && eventType != IRunAndTrack.DISPOSE + if (eventType != ContextEvent.INITIAL && eventType != ContextEvent.DISPOSE && strategy != null && strategy instanceof ISchedulerStrategy) return ((ISchedulerStrategy) strategy).schedule(this, runnable, name, eventType, args); - return runnable.notify(this, name, eventType, args); + return runnable.notify(EclipseContextFactory.createContextEvent(this, eventType, args, name, null)); } protected void schedule(Runnable runnable) { @@ -386,7 +392,7 @@ public class EclipseContext implements IEclipseContext, IDisposable { boolean containsKey = localValues.containsKey(name); Object oldValue = localValues.put(name, value); if (!containsKey || value != oldValue) { - invalidate(name, IRunAndTrack.ADDED); + invalidate(name, ContextEvent.ADDED); } } diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ValueComputation.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ValueComputation.java index 8eaa080f8..9c0203e40 100644 --- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ValueComputation.java +++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ValueComputation.java @@ -10,9 +10,10 @@ *******************************************************************************/ package org.eclipse.e4.core.services.internal.context; +import org.eclipse.e4.core.services.context.ContextEvent; + import org.eclipse.e4.core.services.context.IContextFunction; import org.eclipse.e4.core.services.context.IEclipseContext; -import org.eclipse.e4.core.services.context.spi.IRunAndTrack; public class ValueComputation extends Computation { Object cachedValue; @@ -108,7 +109,7 @@ public class ValueComputation extends Computation { final protected void doHandleInvalid(IEclipseContext context, String name, int eventType) { this.originatingContext.invalidate(this.name, - eventType == IRunAndTrack.DISPOSE ? IRunAndTrack.REMOVED : eventType); + eventType == ContextEvent.DISPOSE ? ContextEvent.REMOVED : eventType); } final Object get(Object[] arguments) { |