Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[platform-ui-dev] Context API confusion (very long)

Hola.

There seems to be a lot of API related to contexts floating around, but I 
can't figure out which is the right one for me. Get comfortable. ;-)

############################################
#  Background info to make sure I have my story straight
############################################
A workbench page can return an IWorkbenchPageContextSupport, which can then 
provide me an ICompoundContextActivationService. This service allows me to 
register an IContextActivationServiceListener. The listener, in turn, is 
notified of ContextActivationServiceEvents, which can tell me which 
IContextActivationService it came from and haveActiveContextIdsChanged(). 
However, it doesn't appear to tell me which contexts have been activated or 
deactivated.

A workbench window can return an IWorkbenchWindowContextSupport, which returns 
an IContextActivationService (not to be confused with an 
ICompoundContextActivationService) which allows me to register an 
IContextActivationServiceListener that can then do the same thing as 
described above.

A workbench can return an IWorkbenchContextSupport, which provides an 
ICompountContextActivationService (like the workbench page, but not the 
workbench window), and an IContextManager. An IContextManager can tell me 
about the set of "defined" context IDs and also about the set of "enabled" 
context IDs. An IContextManager also lets me register an 
IContextManagerListener which is notified of ContextManagerEvents. These 
events tell me which context manager they came from and whether the set of 
defined or enabled contexts has changed. But it doesn't tell me *which* 
contexts have been enabled/disabled or defined(/undefined?). An 
IContextManager also provides access to IContext objects. IContexts let you 
register IContextListeners on them and an IContextListener provides a 
ContextEvent, which tells you which context has changed and what has happened 
to it (which property has changed).

There's also this thing called a ContextManagerFactory, which provides a 
static factory method for creating an IMutableContextManager. An 
IMutableContextManager extends IContextManager and lets you set which 
contexts are enabled.

############################################
# Hopes and dreams in Debugland (redux)
############################################
Back in our code I have a view. When the user selects things in the view, I 
want to activate contexts (I know which contextIds to activate). I also have 
a listener. This listener has a set of context IDs that it cares about. When 
these contexts are activated, it wants to know about it so it can respond.

Additionally, I'd like to be able to bind certain actions to contexts so that 
they only appear at the right time. I'd like the actions to respond to the 
contextIds that are activated by the view (and others, but the ones the view 
activates will be the most interesting).

############################################
# Now I'm in trouble...
############################################
For my view to activate contexts, I need an IMutableContextManager. However, 
the only API I've found that provides an IMutableContextManager is the 
ContextManagerFactory and the context manager that it returns seems to be 
totally disconnected from the rest of the workbench.

Currently, that's what I do. The view creates its own IMutableContextManager 
and activates/deactivates contexts in this manager. My listener then 
registers as an IContextListener on all of the context manager's IContexts.

The problem here, of course, is that I'm in a context manager that's separated 
from reality. Activating contexts in my context manager won't cause the 
action (command) filtering that we want. It also means that if someone other 
than the view activates one of the interesting contextIds, my listener won't 
hear about it.

############################################
# Gimme, gimme :-)
############################################
Based on all this, I have some requests for the API.

1. Provide IMutableContextManagers. For clients to be able to activate 
contexts at the various levels, the API needs to expose 
IMutableContextManagers. I haven't found a way to get to one from the 
workbench, window, or page level. In fact, IMutableContextManagers seem a lot 
more interesting than IContextActivationServices, which they currently 
provide.
2. IContextActivationService seems to promise more than it delivers. In the 
class comment, it says that these things are supposed to "allow clients to 
manage context activation," but I don't see anything on the API that lets you 
manage things. Only access what's currently active. As they stand now, in 
fact, I don't know why a client would want one of these. Maybe the JavaDoc 
could explain?
3. Beef up the description of the various I*ContextSupport level. Trying to 
figure out which level to use is tough right now. It would be nice if the 
JavaDoc would provide examples of when you'd want to use each level.
4. Provide fewer "supports". Having separate I*ContextSupport interfaces for 
every level makes it really hard (for me, at least) to get your head around 
the API. Providing support at every level might be necessary (but I can't 
really tell without #1), but it would make things simpler for clients if each 
level at least provided the same kind of object.
5. Make the I*ContextSupports consistent? I don't understand why the top and 
bottom levels (IWorkbench and IWorkbenchPage) provide 
ICompountContextActivationServices but the middle layer (IWorkbenchWindow) 
provides an IContextActivationService. If this arrangement is intentional, 
could the reason be explained in the JavaDoc? If it's not, then making all 
three levels consistent would make the APIs a little less confusing.
6. Add information to the IContext*Listeners' events. Clients (well, me 
anyway) need to know *what* has changed, not just that something has changed. 
Instead of methods like haveActiveContextIdsChanged(), maybe provide 
getActivatedContextIds() which returns all context IDs that have been 
activated? If nothing's changed, you return an empty list. This is just like 
returning false to the current method. But if they *have* changed, you can 
now tell clients which contexts have been activated so they don't have to go 
grovelling.
7. Reduce the number of listeners. Being able to register as a listener on a 
"context activation service," "context manager," *and* a context seems like 
way too much. It's another of those things like #2 that makes it hard to get 
your head around the API. Do I want to be an 
IContextServiceActivationListener, an IContextManagerListener, or an 
IContextListener? I really just want to have one listener interface that is 
informed about context events. The events should be able to tell me all the 
relevant info - which contexts were defined, which were enabled, and which 
were disabled?
8. Define the difference between "active" and "enabled." Maybe it's defined 
somewhere, but I haven't bumped into it. An IContextActivationService talks 
about contexts in terms of "activation" and an IContextManager talks in terms 
of "enablement" (and "defined", but I think that term is pretty 
self-explanatory).  IContexts talk about *themselves* in terms of enablement 
and make no mention of activation. Are the "active" references in other 
places just holdovers from a period where that was the term for "enabled"? Or 
is there a difference? If so, can this difference be explained in the 
JavaDoc? If not, can all references to "active" be updated to "enabled" for 
consistency?

If you made it through all this, thanks for your patience. I'll understand if 
it takes a few days to get some answers. :-) 

Thanks,
- Jared



Back to the top