Project

General

Profile

Download (10.3 KB) Statistics
| Branch: | Tag: | Revision:
1
Some notes about the CNF in attempt to understand things.
2

    
3
30 Nov 08 FRU
4

    
5
Documentation notes:
6

    
7
There is some good text potentially for the docs in:
8

    
9
https://bugs.eclipse.org/bugs/show_bug.cgi?id=195595
10

    
11

    
12

    
13
Navigator Content
14

    
15
The purpose of the navigatorContent extension (NCE) is to bind a content provider
16
and label provider to the navigator under the right circumstances depending
17
on what is selected.
18

    
19
A navigator content descriptor has a one-to-one correspondence with the
20
navigator content extension, which is the higher level object representing
21
the navigator content.
22

    
23
Overriding
24

    
25
An NCE may specify that it overrides another through the user of the override
26
mechanism where it specifies the NCE extension ID of the extension to override.
27

    
28
When doing the processing associated with the label and content provider, it is possible
29
that multiple NCEs meet the criteria for processing based on their triggerPoints and/or 
30
possibleChildren.  When this happens, the NCEs are ordered in a tree based
31
on the overrides specification, and then with that based on priority.
32
The first NCE in the tree that provides the answer (label or content) being
33
sought is used.
34

    
35
When the NCE is bound to the viewer (using the contentExtension element) it may
36
specify that that NCE serves as "root content" for that viewer, which allows
37
the viewer to start with an initial set of NCEs to process the root(s) [why exactly --
38
I understand intuitively but can't put it into words].
39

    
40

    
41
Pipelining
42

    
43
In some cases, it is desirable to have multiple NCEs be invoked during
44
content provider processing to modify the objects to be returned by the
45
content provider.  This is done using the pipelining mechanism where each NCE
46
in the tree has the opportunity to modify the objects to be returned by the
47
content provider.  There are also hooks for these pipelined NCEs to 
48
be invoked at the Add/Remove/Update/Refresh methods on the viewer.
49

    
50

    
51
Selecting a Content Extension (NCE)
52

    
53
This is done either through the possibleChildren or triggerPoints expression
54
on the NCE.  The enablement expression expression specifies the same expression
55
for both triggerPoints and possibleChildren.
56

    
57
The triggerPoints expression is used:
58

    
59
- by the NavigatorContentServiceContentProvider
60
to find extensions for getElements() (through the root content extensions) 
61
or getChildren().  Given a parent node, that content extension is used
62
to determine what children to provide.
63
- by the NavigatorPipelineService for ???
64

    
65
The possibleChildren expression is used for all other cases, which include:
66

    
67
- Label/icon/description provider
68
- Selecting the NCE for a drop
69

    
70
The current documentation on these uses is incorrect, in particular for 
71
the label provides, it says that the triggerPoints expression is used, but
72
it's not.
73

    
74

    
75

    
76

    
77

    
78

    
79
Dependency
80

    
81
Questions/Issues:
82

    
83
1) In NavigatorContentServicedLabelProvider, seems that we look for
84
label providers by looking for matching NCEs by possibleChild.
85
However the documentation is clear that content and label providers
86
are found by triggerPoint, possibleChild is used only in the content
87
provider getParent() case.
88

    
89
<mde>The API documentation for label providers is wrong. It has always been 
90
the case that label providers rely on the possibleChildren; we should
91
 correct the doc since actual implementations are relying on the 
92
 behavior of label providers using possible children (but only in 
93
 cases where the framework can't determine which extension contributed 
94
 the content with its short term memory mechanism). 
95
 Other parts of the framework (like the DND Drop Handlers) also rely on 
96
 possible children to determine which content extension's handlers 
97
 should be invoked when processing a drop operation. </mde>
98

    
99

    
100
2) In NavigatorContentServiceLabel provider, there seems to be special
101
processing to handle overriding instead of using the normal processing
102
to get only the relevant NCEs.  Also, the way to get the NCEs is
103
different depending on whether doing a getImage() or getForeground()
104
for example and I don't understand why.  Also
105
NavigatorContentServiceDescriptionProvider does not seem to consider
106
overrides at all.  This all seems wrong.
107

    
108
<mde>
109
The content extension has alot of complexity because it has to 
110
determine the overrides for each individual child along the path. 
111
Labels are a bit simpler because only one value can be returned. 
112
The override logic recursively walks the override path by the highest 
113
priority label provider. Overriding label providers can opt not to 
114
return a label (e.g. null), and the framework will fall back on the 
115
base label provider to provide a value.
116

    
117
The getForeground()/getFont() cases weren't retrofitted for 
118
overriding values. This was just a legacy/point in time and 
119
is arguably a bug. The Font and Color providers were added to 
120
support the Team providers (they weren't part of the original product 
121
framework). If anything, the getFont()/Foreground/Background() 
122
methods should be retrofitted to follow the patter in getText/Image().
123
</mde>
124

    
125

    
126
3) The triggerPoints and possibleChildren descriptions in the exsd are
127
confusing:
128

    
129
"The triggerPoints expression defines the nodes in a tree that should
130
cause this extension to be invoked for children."
131

    
132
"The possibleChildren expression defines the nodes in a tree that
133
could be contributed by this extension.  Clients should describes when
134
this content extension could provide a parent for elements that match
135
the expression."
136

    
137
I think a clearer description is:
138

    
139
The triggerPoints expression defines the tree nodes for which this
140
extension (and associated content/label providers) is to be invoked.
141

    
142
<mde>Remove "label providers" and we're good. </mde>
143

    
144
The possibleChildren expression defines the content provider to be
145
selected when processing the ITreeContentProvider.getParent() call.
146

    
147
<mde>As well as the DND Drop Handler and Action Providers.</mde>
148

    
149
4) Why is the overridden tree computed only on
150
findDescriptorsForPossibleChild and not for
151
findDescriptorsForTriggerPoint?  The extension point documentation for
152
the overrides element says that the overrides only applied to
153
triggerpoints, it does not mention possibleChildren (except in
154
reference to the OnlySuppressedifExtVisibleAndActive option is set,
155
but it still seems to say that only triggerPoints is actually used).
156

    
157
<mde>It might be worth setting up an hour to go through a deep dive 
158
for this material. If I recall correctly, there was a challenge in 
159
computing all of the triggerpoint overrides a priori, but the 
160
overrides are used. The NavigatorContentServiceContentProvider 
161
processes a given element for children (e.g. getChildren()), 
162
and then invokes the overridden providers directly (from within 
163
the Service content provider) to compute the overridden tree. 
164
The possible children through doesn't have a use case like this, 
165
and so these can be computed and returned as needed.</mde>
166

    
167
5) More confusion (from the overrides exsd):
168

    
169
"InvokeAlwaysRegardlessOfSuppressedExt (default): Indicates that this
170
extension is a first class extension; it should be given opportunities
171
to contribute content regardless if its suppressedExtensionId is
172
visible or active to the viewer. Thus, the extension is a first-class
173
extension and an overriding extension. It will be invoked whenever its
174
triggerPoints expression is matched. When the suppressed extension and
175
its triggerPoints extension is matched, it will be invoked with the
176
contributed items from its suppressed extension; the suppressed
177
extension will not be given an opportunity to directly contribute."
178

    
179
The last sentence of this is unclear.  I think it would be better (and
180
consistent with the rest of the explanations) if the suppressed
181
extension was just suppressed, it is never invoked at all.
182

    
183
<mde>The use cases here are as follows:
184

    
185
1. I want to contribute my stuff, and I want to specialize an existing provider 
186
like Java, and
187

    
188
2. I want to just specialize another provider, and if it's not turned on, I don't 
189
even need to be considered.
190

    
191
So in neither case is it completely suppressed, but rather in case 2 it acts 
192
like a domino of its source provider. I just want to make sure we don't 
193
lose this meaning in the update of the documentation </mde>
194

    
195

    
196
6) Should the NCE class and NavigatorContentDescriptor classes be
197
combined? They seem to be one-to-one and there is a lot of code that
198
seems to convert from one to another for no good reason.
199

    
200
<mde>The Descriptor/Extension pattern is used for every part of the framework, here's why:
201

    
202
A Manager handles Descriptors; Managers are singletons, and each known extension
203
has exactly one Descriptor. The state associated with a Descriptor is just an API 
204
convenience layer on top of the IConfigurationElement API. These are relatively 
205
lightweight, and their lifecycle is the lifecycle of the Manager, which is 
206
effectively the lifecycle of the workbench.
207

    
208
A Service handles Extensions; Services are 1 instance per Common Navigator viewer 
209
(or whatever client is using the Service). Each Service creates an Extension 
210
and manages a map from Descriptor (1 instance for each extension for all 
211
viewers) to its Extension (1 instance for each instance viewer). The Extension 
212
instance creates instances of classes defined by the plugin extension metadata; 
213
each of these instances has an associated lifecycle (init .. do work .. dispose) 
214
and can hold on to system resources (label providers can hold Fonts or Colors, 
215
content providers might talk to a data source across a network). Most of these 
216
classes aren't necessarily designed to be re-entrant (they make assumptions 
217
about the current state of a given viewer, like whether to show 
218
Packages as hierarchical or flattened). So if I create a Project Explorer, 
219
and then separately create a MyCustomView and bind Java to each of them, 
220
I'll have 1 Java Descriptor, and 2 Java Extensions in memory.
221

    
222
Collapsing Descriptors into Extensions would be a fundamental change to the 
223
framework, eliminate the assumption that there's 1 content 
224
provider/label provider/etc for each view instance, and make it hard or 
225
impossible to know when each of the instantiated classes from each 
226
plugin extension can be disposed. I would not recommend this.
227
</mde>
228

    
229

    
230
7) There are substantial chunks of duplicate code where only one
231
line is different between the similar methods.
232

    
233
<mde>If you can provide a few examples, I might be able to provide some 
234
insights here; in many cases, I tried to use the same simple patterns 
235
throughout the frameworks to keep the overall complexity down, which 
236
can lead to this kind of pattern.</mde>
237

    
238

    
(7-7/10)