1
|
/*******************************************************************************
|
2
|
* Copyright (c) 2003, 2010 IBM Corporation and others.
|
3
|
* All rights reserved. This program and the accompanying materials
|
4
|
* are made available under the terms of the Eclipse Public License v1.0
|
5
|
* which accompanies this distribution, and is available at
|
6
|
* http://www.eclipse.org/legal/epl-v10.html
|
7
|
*
|
8
|
* Contributors:
|
9
|
* IBM Corporation - initial API and implementation
|
10
|
* Fair Issac Corp - bug 287103 - NCSLabelProvider does not properly handle overrides
|
11
|
*******************************************************************************/
|
12
|
package org.eclipse.ui.internal.navigator;
|
13
|
|
14
|
import java.util.ArrayList;
|
15
|
import java.util.Collection;
|
16
|
import java.util.Collections;
|
17
|
import java.util.HashMap;
|
18
|
import java.util.HashSet;
|
19
|
import java.util.Iterator;
|
20
|
import java.util.LinkedHashSet;
|
21
|
import java.util.List;
|
22
|
import java.util.ListIterator;
|
23
|
import java.util.Map;
|
24
|
import java.util.Set;
|
25
|
import java.util.SortedSet;
|
26
|
import java.util.TreeSet;
|
27
|
|
28
|
import org.osgi.service.prefs.BackingStoreException;
|
29
|
|
30
|
import org.eclipse.swt.widgets.Shell;
|
31
|
|
32
|
import org.eclipse.core.runtime.IStatus;
|
33
|
import org.eclipse.core.runtime.Platform;
|
34
|
import org.eclipse.core.runtime.SafeRunner;
|
35
|
import org.eclipse.core.runtime.Status;
|
36
|
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
|
37
|
import org.eclipse.core.runtime.preferences.InstanceScope;
|
38
|
|
39
|
import org.eclipse.jface.viewers.ILabelProvider;
|
40
|
import org.eclipse.jface.viewers.ITreeContentProvider;
|
41
|
import org.eclipse.jface.viewers.StructuredViewer;
|
42
|
import org.eclipse.jface.viewers.Viewer;
|
43
|
|
44
|
import org.eclipse.ui.IMemento;
|
45
|
import org.eclipse.ui.internal.navigator.dnd.NavigatorDnDService;
|
46
|
import org.eclipse.ui.internal.navigator.extensions.ExtensionSequenceNumberComparator;
|
47
|
import org.eclipse.ui.internal.navigator.extensions.NavigatorContentDescriptor;
|
48
|
import org.eclipse.ui.internal.navigator.extensions.NavigatorContentDescriptorManager;
|
49
|
import org.eclipse.ui.internal.navigator.extensions.NavigatorContentExtension;
|
50
|
import org.eclipse.ui.internal.navigator.extensions.NavigatorViewerDescriptor;
|
51
|
import org.eclipse.ui.internal.navigator.extensions.NavigatorViewerDescriptorManager;
|
52
|
import org.eclipse.ui.internal.navigator.extensions.StructuredViewerManager;
|
53
|
import org.eclipse.ui.internal.navigator.sorters.NavigatorSorterService;
|
54
|
import org.eclipse.ui.navigator.IDescriptionProvider;
|
55
|
import org.eclipse.ui.navigator.IExtensionActivationListener;
|
56
|
import org.eclipse.ui.navigator.IExtensionStateModel;
|
57
|
import org.eclipse.ui.navigator.IMementoAware;
|
58
|
import org.eclipse.ui.navigator.INavigatorActivationService;
|
59
|
import org.eclipse.ui.navigator.INavigatorContentDescriptor;
|
60
|
import org.eclipse.ui.navigator.INavigatorContentExtension;
|
61
|
import org.eclipse.ui.navigator.INavigatorContentService;
|
62
|
import org.eclipse.ui.navigator.INavigatorContentServiceListener;
|
63
|
import org.eclipse.ui.navigator.INavigatorDnDService;
|
64
|
import org.eclipse.ui.navigator.INavigatorFilterService;
|
65
|
import org.eclipse.ui.navigator.INavigatorPipelineService;
|
66
|
import org.eclipse.ui.navigator.INavigatorSaveablesService;
|
67
|
import org.eclipse.ui.navigator.INavigatorSorterService;
|
68
|
import org.eclipse.ui.navigator.INavigatorViewerDescriptor;
|
69
|
|
70
|
/**
|
71
|
* <p>
|
72
|
* Provides centralized access to the information provided by
|
73
|
* NavigatorContentExtensions. Can be instantiated as needed, but should be
|
74
|
* cached for active viewers. Information specific to a given viewer will be
|
75
|
* cached by the NavigatorContentService, not including ContentProviders and
|
76
|
* Label Providers created by {@link #createCommonContentProvider()}and
|
77
|
* {@link #createCommonLabelProvider()}respectively.
|
78
|
* </p>
|
79
|
*
|
80
|
* <p>
|
81
|
* The following class is experimental until fully documented.
|
82
|
* </p>
|
83
|
*/
|
84
|
public class NavigatorContentService implements IExtensionActivationListener,
|
85
|
IMementoAware, INavigatorContentService {
|
86
|
|
87
|
/**
|
88
|
*
|
89
|
*/
|
90
|
public static final String WIDGET_KEY = "org.eclipse.ui.navigator"; //$NON-NLS-1$
|
91
|
|
92
|
private static final NavigatorContentDescriptorManager CONTENT_DESCRIPTOR_REGISTRY = NavigatorContentDescriptorManager
|
93
|
.getInstance();
|
94
|
|
95
|
private static final NavigatorViewerDescriptorManager VIEWER_DESCRIPTOR_REGISTRY = NavigatorViewerDescriptorManager
|
96
|
.getInstance();
|
97
|
|
98
|
private static final ITreeContentProvider[] NO_CONTENT_PROVIDERS = new ITreeContentProvider[0];
|
99
|
|
100
|
private static final ILabelProvider[] NO_LABEL_PROVIDERS = new ILabelProvider[0];
|
101
|
|
102
|
private static final INavigatorContentDescriptor[] NO_DESCRIPTORS = new INavigatorContentDescriptor[0];
|
103
|
|
104
|
private static final String[] NO_EXTENSION_IDS = new String[0];
|
105
|
|
106
|
private final NavigatorViewerDescriptor viewerDescriptor;
|
107
|
|
108
|
private final List listeners = new ArrayList();
|
109
|
|
110
|
/*
|
111
|
* A map of (String-based-Navigator-Content-Extension-IDs,
|
112
|
* NavigatorContentExtension-objects)-pairs
|
113
|
*/
|
114
|
private final Map contentExtensions = new HashMap();
|
115
|
|
116
|
private StructuredViewerManager structuredViewerManager;
|
117
|
|
118
|
private ITreeContentProvider[] rootContentProviders;
|
119
|
|
120
|
private ITreeContentProvider contentProvider;
|
121
|
|
122
|
/*
|
123
|
* Used when providing objects to the CommonViewer by the contentProvider
|
124
|
* to record the object/description associations which are when stored
|
125
|
* in the Tree associated with the viewer.
|
126
|
*/
|
127
|
private Map contributionMemory;
|
128
|
private Map contributionMemoryFirstClass;
|
129
|
|
130
|
private ILabelProvider labelProvider;
|
131
|
|
132
|
private final VisibilityAssistant assistant;
|
133
|
|
134
|
private NavigatorFilterService navigatorFilterService;
|
135
|
|
136
|
private NavigatorSorterService navigatorSorterService;
|
137
|
|
138
|
private INavigatorPipelineService navigatorPipelineService;
|
139
|
|
140
|
private INavigatorDnDService navigatorDnDService;
|
141
|
|
142
|
private INavigatorActivationService navigatorActivationService;
|
143
|
|
144
|
private NavigatorSaveablesService navigatorSaveablesService;
|
145
|
|
146
|
private NavigatorExtensionStateService navigatorExtensionStateService;
|
147
|
|
148
|
private IDescriptionProvider descriptionProvider;
|
149
|
|
150
|
private boolean contentProviderInitialized;
|
151
|
|
152
|
private boolean labelProviderInitialized;
|
153
|
|
154
|
private boolean isDisposed;
|
155
|
|
156
|
/**
|
157
|
* @param aViewerId
|
158
|
* The viewer id for this content service; normally from the
|
159
|
* <b>org.eclipse.ui.views</b> extension.
|
160
|
*/
|
161
|
public NavigatorContentService(String aViewerId) {
|
162
|
super();
|
163
|
aViewerId = aViewerId != null ? aViewerId : ""; //$NON-NLS-1$
|
164
|
viewerDescriptor = VIEWER_DESCRIPTOR_REGISTRY
|
165
|
.getNavigatorViewerDescriptor(aViewerId);
|
166
|
assistant = new VisibilityAssistant(viewerDescriptor,
|
167
|
getActivationService());
|
168
|
getActivationService().addExtensionActivationListener(this);
|
169
|
contributionMemory = new HashMap();
|
170
|
contributionMemoryFirstClass = new HashMap();
|
171
|
}
|
172
|
|
173
|
/**
|
174
|
* @param aViewerId
|
175
|
* The viewer id for this content service; normally from the
|
176
|
* <b>org.eclipse.ui.views</b> extension.
|
177
|
* @param aViewer
|
178
|
* The viewer that this content service will be associated with.
|
179
|
*/
|
180
|
public NavigatorContentService(String aViewerId, StructuredViewer aViewer) {
|
181
|
this(aViewerId);
|
182
|
structuredViewerManager = new StructuredViewerManager(aViewer, this);
|
183
|
}
|
184
|
|
185
|
public String[] getVisibleExtensionIds() {
|
186
|
|
187
|
List visibleExtensionIds = new ArrayList();
|
188
|
|
189
|
NavigatorContentDescriptor[] descriptors = CONTENT_DESCRIPTOR_REGISTRY
|
190
|
.getAllContentDescriptors();
|
191
|
for (int i = 0; i < descriptors.length; i++) {
|
192
|
if (assistant.isVisible(descriptors[i].getId())) {
|
193
|
visibleExtensionIds.add(descriptors[i].getId());
|
194
|
}
|
195
|
}
|
196
|
if (visibleExtensionIds.isEmpty()) {
|
197
|
return NO_EXTENSION_IDS;
|
198
|
}
|
199
|
return (String[]) visibleExtensionIds
|
200
|
.toArray(new String[visibleExtensionIds.size()]);
|
201
|
|
202
|
}
|
203
|
|
204
|
public INavigatorContentDescriptor[] getVisibleExtensions() {
|
205
|
List visibleDescriptors = new ArrayList();
|
206
|
|
207
|
NavigatorContentDescriptor[] descriptors = CONTENT_DESCRIPTOR_REGISTRY
|
208
|
.getAllContentDescriptors();
|
209
|
for (int i = 0; i < descriptors.length; i++) {
|
210
|
if (assistant.isVisible(descriptors[i].getId())) {
|
211
|
visibleDescriptors.add(descriptors[i]);
|
212
|
}
|
213
|
}
|
214
|
if (visibleDescriptors.isEmpty()) {
|
215
|
return NO_DESCRIPTORS;
|
216
|
}
|
217
|
return (INavigatorContentDescriptor[]) visibleDescriptors
|
218
|
.toArray(new INavigatorContentDescriptor[visibleDescriptors
|
219
|
.size()]);
|
220
|
|
221
|
}
|
222
|
|
223
|
/* package */INavigatorContentDescriptor[] getActiveDescriptorsWithSaveables() {
|
224
|
List result = new ArrayList();
|
225
|
|
226
|
NavigatorContentDescriptor[] descriptors = CONTENT_DESCRIPTOR_REGISTRY
|
227
|
.getContentDescriptorsWithSaveables();
|
228
|
for (int i = 0; i < descriptors.length; i++) {
|
229
|
if (assistant.isVisible(descriptors[i].getId())
|
230
|
&& assistant.isActive(descriptors[i])) {
|
231
|
result.add(descriptors[i]);
|
232
|
}
|
233
|
}
|
234
|
if (result.isEmpty()) {
|
235
|
return NO_DESCRIPTORS;
|
236
|
}
|
237
|
return (INavigatorContentDescriptor[]) result
|
238
|
.toArray(new INavigatorContentDescriptor[result.size()]);
|
239
|
|
240
|
}
|
241
|
|
242
|
/*
|
243
|
* (non-Javadoc)
|
244
|
*
|
245
|
* @see
|
246
|
* org.eclipse.ui.navigator.INavigatorContentService#bindExtensions(java
|
247
|
* .lang.String[], boolean)
|
248
|
*/
|
249
|
public INavigatorContentDescriptor[] bindExtensions(String[] extensionIds,
|
250
|
boolean isRoot) {
|
251
|
if (extensionIds == null || extensionIds.length == 0) {
|
252
|
return NO_DESCRIPTORS;
|
253
|
}
|
254
|
|
255
|
for (int i = 0; i < extensionIds.length; i++) {
|
256
|
assistant.bindExtensions(extensionIds, isRoot);
|
257
|
}
|
258
|
Set boundDescriptors = new HashSet();
|
259
|
INavigatorContentDescriptor descriptor;
|
260
|
for (int i = 0; i < extensionIds.length; i++) {
|
261
|
descriptor = CONTENT_DESCRIPTOR_REGISTRY
|
262
|
.getContentDescriptor(extensionIds[i]);
|
263
|
if (descriptor != null) {
|
264
|
boundDescriptors.add(descriptor);
|
265
|
}
|
266
|
}
|
267
|
|
268
|
if (boundDescriptors.size() == 0) {
|
269
|
return NO_DESCRIPTORS;
|
270
|
}
|
271
|
|
272
|
if (Policy.DEBUG_EXTENSION_SETUP) {
|
273
|
System.out.println("bindExtensions: " + //$NON-NLS-1$
|
274
|
boundDescriptors);
|
275
|
}
|
276
|
return (INavigatorContentDescriptor[]) boundDescriptors
|
277
|
.toArray(new INavigatorContentDescriptor[boundDescriptors
|
278
|
.size()]);
|
279
|
|
280
|
}
|
281
|
|
282
|
/*
|
283
|
* (non-Javadoc)
|
284
|
*
|
285
|
* @seeorg.eclipse.ui.internal.navigator.INavigatorContentService#
|
286
|
* createCommonContentProvider()
|
287
|
*/
|
288
|
public ITreeContentProvider createCommonContentProvider() {
|
289
|
if (contentProviderInitialized) {
|
290
|
return contentProvider;
|
291
|
}
|
292
|
synchronized (this) {
|
293
|
if (contentProvider == null) {
|
294
|
contentProvider = new NavigatorContentServiceContentProvider(
|
295
|
this);
|
296
|
}
|
297
|
contentProviderInitialized = true;
|
298
|
}
|
299
|
return contentProvider;
|
300
|
}
|
301
|
|
302
|
/*
|
303
|
* (non-Javadoc)
|
304
|
*
|
305
|
* @seeorg.eclipse.ui.internal.navigator.INavigatorContentService#
|
306
|
* createCommonLabelProvider()
|
307
|
*/
|
308
|
public ILabelProvider createCommonLabelProvider() {
|
309
|
if (labelProviderInitialized) {
|
310
|
return labelProvider;
|
311
|
}
|
312
|
synchronized (this) {
|
313
|
if (labelProvider == null) {
|
314
|
labelProvider = new NavigatorContentServiceLabelProvider(this);
|
315
|
}
|
316
|
labelProviderInitialized = true;
|
317
|
}
|
318
|
return labelProvider;
|
319
|
}
|
320
|
|
321
|
/*
|
322
|
* (non-Javadoc)
|
323
|
*
|
324
|
* @seeorg.eclipse.ui.navigator.INavigatorContentService#
|
325
|
* createCommonDescriptionProvider()
|
326
|
*/
|
327
|
public IDescriptionProvider createCommonDescriptionProvider() {
|
328
|
if (descriptionProvider != null) {
|
329
|
return descriptionProvider;
|
330
|
}
|
331
|
synchronized (this) {
|
332
|
if (descriptionProvider == null) {
|
333
|
descriptionProvider = new NavigatorContentServiceDescriptionProvider(
|
334
|
this);
|
335
|
}
|
336
|
}
|
337
|
return descriptionProvider;
|
338
|
}
|
339
|
|
340
|
/*
|
341
|
* (non-Javadoc)
|
342
|
*
|
343
|
* @see org.eclipse.ui.internal.navigator.INavigatorContentService#dispose()
|
344
|
*/
|
345
|
public void dispose() {
|
346
|
if (navigatorSaveablesService != null) {
|
347
|
assistant.removeListener(navigatorSaveablesService);
|
348
|
}
|
349
|
if (navigatorSorterService != null) {
|
350
|
assistant.removeListener(navigatorSorterService);
|
351
|
}
|
352
|
synchronized (this) {
|
353
|
for (Iterator contentItr = contentExtensions.values().iterator(); contentItr
|
354
|
.hasNext();) {
|
355
|
((NavigatorContentExtension) contentItr.next()).dispose();
|
356
|
}
|
357
|
}
|
358
|
getActivationService().removeExtensionActivationListener(this);
|
359
|
assistant.dispose();
|
360
|
isDisposed = true;
|
361
|
}
|
362
|
|
363
|
protected void updateService(Viewer aViewer, Object anOldInput,
|
364
|
Object aNewInput) {
|
365
|
|
366
|
// Prevents the world from being started again once we have been disposed. In
|
367
|
// the dispose process, the ContentViewer will call setInput() on the
|
368
|
// NavigatorContentServiceContentProvider, which gets us here
|
369
|
if (isDisposed)
|
370
|
return;
|
371
|
synchronized (this) {
|
372
|
|
373
|
if (structuredViewerManager == null) {
|
374
|
structuredViewerManager = new StructuredViewerManager((StructuredViewer) aViewer, this);
|
375
|
structuredViewerManager.inputChanged(anOldInput, aNewInput);
|
376
|
} else {
|
377
|
structuredViewerManager.inputChanged(aViewer, anOldInput,
|
378
|
aNewInput);
|
379
|
}
|
380
|
|
381
|
for (Iterator contentItr = contentExtensions.values().iterator(); contentItr
|
382
|
.hasNext();) {
|
383
|
NavigatorContentExtension ext = (NavigatorContentExtension) contentItr
|
384
|
.next();
|
385
|
if (ext.isLoaded()) {
|
386
|
structuredViewerManager
|
387
|
.initialize(ext.internalGetContentProvider());
|
388
|
}
|
389
|
}
|
390
|
|
391
|
rootContentProviders = extractContentProviders(findRootContentExtensions(aNewInput));
|
392
|
}
|
393
|
}
|
394
|
|
395
|
public IExtensionStateModel findStateModel(String anExtensionId) {
|
396
|
if (anExtensionId == null) {
|
397
|
return null;
|
398
|
}
|
399
|
INavigatorContentDescriptor desc = CONTENT_DESCRIPTOR_REGISTRY
|
400
|
.getContentDescriptor(anExtensionId);
|
401
|
if (desc == null) {
|
402
|
return null;
|
403
|
}
|
404
|
INavigatorContentExtension ext = getExtension(desc);
|
405
|
if (ext == null) {
|
406
|
return null;
|
407
|
}
|
408
|
return ext.getStateModel();
|
409
|
}
|
410
|
|
411
|
/**
|
412
|
* <p>
|
413
|
* Return all of the content providers that are relevant for the viewer. The
|
414
|
* viewer is determined by the ID used to create the
|
415
|
* INavigatorContentService ({@link #getViewerId() }). See
|
416
|
* {@link #createCommonContentProvider() } for more information about how
|
417
|
* content providers are located for the root of the viewer. The root
|
418
|
* content providers are calculated once. If a new element is supplied, a
|
419
|
* client must call {@link #update() } prior in order to reset the calculated
|
420
|
* root providers.
|
421
|
* </p>
|
422
|
*
|
423
|
* @param anElement
|
424
|
* An element from the tree (generally the input of the viewer)
|
425
|
* @return The set of content providers that can provide root elements for a
|
426
|
* viewer.
|
427
|
*/
|
428
|
public ITreeContentProvider[] findRootContentProviders(Object anElement) {
|
429
|
if (rootContentProviders != null) {
|
430
|
return rootContentProviders;
|
431
|
}
|
432
|
synchronized (this) {
|
433
|
if (rootContentProviders == null) {
|
434
|
rootContentProviders = extractContentProviders(findRootContentExtensions(anElement));
|
435
|
|
436
|
}
|
437
|
}
|
438
|
return rootContentProviders;
|
439
|
}
|
440
|
|
441
|
/**
|
442
|
* Returns the list of extensions that should be considered as possible
|
443
|
* contributors of CNF artifacts (labels, sorters, ...). The algorithm
|
444
|
* first considers the source of contribution and its overrides, and then
|
445
|
* any possibleChildren and their overrides in order.
|
446
|
*
|
447
|
* @param anElement
|
448
|
* An element from the tree (any element contributed to the
|
449
|
* tree).
|
450
|
* @return A Collection of NCEs sorted in the correct order for label provider application
|
451
|
*/
|
452
|
public Collection findPossibleLabelExtensions(Object anElement) {
|
453
|
LinkedHashSet contributors = new LinkedHashSet();
|
454
|
INavigatorContentDescriptor sourceDescriptor = getSourceOfContribution(anElement);
|
455
|
|
456
|
// This is a TreeSet sorted ascending
|
457
|
Set possibleChildDescriptors = findDescriptorsWithPossibleChild(anElement, false);
|
458
|
|
459
|
// Add the source so that it gets sorted into the right place
|
460
|
if (sourceDescriptor != null) {
|
461
|
possibleChildDescriptors.add(sourceDescriptor);
|
462
|
}
|
463
|
|
464
|
for (Iterator iter = possibleChildDescriptors.iterator(); iter.hasNext();) {
|
465
|
NavigatorContentDescriptor ncd = (NavigatorContentDescriptor) iter.next();
|
466
|
findOverridingLabelExtensions(anElement, ncd, contributors);
|
467
|
}
|
468
|
|
469
|
return contributors;
|
470
|
}
|
471
|
|
472
|
private void findOverridingLabelExtensions(Object anElement,
|
473
|
INavigatorContentDescriptor descriptor, LinkedHashSet contributors) {
|
474
|
ListIterator iter = ((NavigatorContentDescriptor) descriptor).getOverridingExtensionsListIterator(false);
|
475
|
while (iter.hasPrevious()) {
|
476
|
INavigatorContentDescriptor child = (INavigatorContentDescriptor) iter.previous();
|
477
|
if (assistant.isVisibleAndActive(child) && child.isPossibleChild(anElement)) {
|
478
|
findOverridingLabelExtensions(anElement, child, contributors);
|
479
|
}
|
480
|
}
|
481
|
contributors.add(getExtension(descriptor));
|
482
|
}
|
483
|
|
484
|
/**
|
485
|
*
|
486
|
* The label provider that is are enabled for the given element.
|
487
|
* A label provider is 'enabled' if its corresponding content provider
|
488
|
* returned the element.
|
489
|
*
|
490
|
* @param anElement
|
491
|
* An element from the tree (any element contributed to the
|
492
|
* tree).
|
493
|
* @return The label provider
|
494
|
*/
|
495
|
public ILabelProvider[] findRelevantLabelProviders(Object anElement) {
|
496
|
Collection extensions = findPossibleLabelExtensions(anElement);
|
497
|
|
498
|
if (extensions.size() == 0) {
|
499
|
return NO_LABEL_PROVIDERS;
|
500
|
}
|
501
|
List resultProvidersList = new ArrayList();
|
502
|
for (Iterator itr = extensions.iterator(); itr.hasNext();) {
|
503
|
resultProvidersList.add(((NavigatorContentExtension) itr.next()).getLabelProvider());
|
504
|
}
|
505
|
return (ILabelProvider[]) resultProvidersList.toArray(new ILabelProvider[resultProvidersList.size()]);
|
506
|
}
|
507
|
|
508
|
/**
|
509
|
* Search for extensions that declare the given element in their
|
510
|
* <b>triggerPoints</b> expression.
|
511
|
*
|
512
|
* @param anElement
|
513
|
* The element to use in the query
|
514
|
* @return The set of {@link INavigatorContentExtension}s that are
|
515
|
* <i>visible</i> and <i>active</i> for this content service and
|
516
|
* either declared through a
|
517
|
* <b>org.eclipse.ui.navigator.viewer/viewerContentBinding</b> to be
|
518
|
* a root element or have a <b>triggerPoints</b> expression that is
|
519
|
* <i>enabled</i> for the given element.
|
520
|
*/
|
521
|
public Set findRootContentExtensions(Object anElement) {
|
522
|
return findRootContentExtensions(anElement, true);
|
523
|
}
|
524
|
|
525
|
/**
|
526
|
* Search for extensions that declare the given element in their
|
527
|
* <b>triggerPoints</b> expression.
|
528
|
*
|
529
|
* @param anElement
|
530
|
* The element to use in the query
|
531
|
* @param toRespectViewerRoots
|
532
|
* True respect the <b>viewerContentBinding</b>s, False will look
|
533
|
* only for matching <b>triggerPoints</b> expressions.
|
534
|
* @return The set of {@link INavigatorContentExtension}s that are
|
535
|
* <i>visible</i> and <i>active</i> for this content service and
|
536
|
* either declared through a
|
537
|
* <b>org.eclipse.ui.navigator.viewer/viewerContentBinding</b> to be
|
538
|
* a root element or have a <b>triggerPoints</b> expression that is
|
539
|
* <i>enabled</i> for the given element.
|
540
|
*/
|
541
|
public Set findRootContentExtensions(Object anElement,
|
542
|
boolean toRespectViewerRoots) {
|
543
|
|
544
|
SortedSet rootExtensions = new TreeSet(
|
545
|
ExtensionSequenceNumberComparator.INSTANCE);
|
546
|
if (toRespectViewerRoots
|
547
|
/*&& viewerDescriptor.hasOverriddenRootExtensions()*/) {
|
548
|
|
549
|
NavigatorContentDescriptor[] descriptors = CONTENT_DESCRIPTOR_REGISTRY
|
550
|
.getAllContentDescriptors();
|
551
|
|
552
|
NavigatorContentExtension extension = null;
|
553
|
for (int i = 0; i < descriptors.length; i++) {
|
554
|
if (isActive(descriptors[i].getId())
|
555
|
&& isRootExtension(descriptors[i].getId())) {
|
556
|
extension = getExtension(descriptors[i]);
|
557
|
if (!extension.hasLoadingFailed()) {
|
558
|
rootExtensions.add(extension);
|
559
|
}
|
560
|
}
|
561
|
}
|
562
|
}
|
563
|
if (rootExtensions.isEmpty()) {
|
564
|
return findContentExtensionsByTriggerPoint(anElement);
|
565
|
}
|
566
|
return rootExtensions;
|
567
|
}
|
568
|
|
569
|
/**
|
570
|
* Search for extensions that declare the given element in their
|
571
|
* <b>possibleChildren</b> expression.
|
572
|
*
|
573
|
* @param anElement
|
574
|
* The element to use in the query
|
575
|
* @return The set of {@link INavigatorContentExtension}s that are
|
576
|
* <i>visible</i> and <i>active</i> for this content service and
|
577
|
* have a <b>possibleChildren</b> expression that is <i>enabled</i>
|
578
|
* for the given element.
|
579
|
*/
|
580
|
public Set findOverrideableContentExtensionsForPossibleChild(
|
581
|
Object anElement) {
|
582
|
Set overrideableExtensions = new TreeSet(
|
583
|
ExtensionSequenceNumberComparator.INSTANCE);
|
584
|
Set descriptors = findDescriptorsWithPossibleChild(anElement, false);
|
585
|
for (Iterator iter = descriptors.iterator(); iter.hasNext();) {
|
586
|
INavigatorContentDescriptor descriptor = (INavigatorContentDescriptor) iter
|
587
|
.next();
|
588
|
if (descriptor.hasOverridingExtensions()) {
|
589
|
overrideableExtensions.add(getExtension(descriptor));
|
590
|
}
|
591
|
}
|
592
|
return overrideableExtensions;
|
593
|
}
|
594
|
|
595
|
/*
|
596
|
* (Non-Javadoc)
|
597
|
*
|
598
|
* @see INavigatorContentService#getContentDescriptorById(String)
|
599
|
*/
|
600
|
public INavigatorContentDescriptor getContentDescriptorById(
|
601
|
String anExtensionId) {
|
602
|
return CONTENT_DESCRIPTOR_REGISTRY.getContentDescriptor(anExtensionId);
|
603
|
}
|
604
|
|
605
|
/**
|
606
|
*
|
607
|
* @param anExtensionId
|
608
|
* The id used to define the
|
609
|
* <b>org.eclipse.ui.navigator.navigatorContent
|
610
|
* /navigatorContent</b> extension.
|
611
|
* @return An instance of the content extension for the given extension id.
|
612
|
* May return <b>null</b> if the id is invalid.
|
613
|
*/
|
614
|
public INavigatorContentExtension getContentExtensionById(
|
615
|
String anExtensionId) {
|
616
|
NavigatorContentDescriptor descriptor = CONTENT_DESCRIPTOR_REGISTRY
|
617
|
.getContentDescriptor(anExtensionId);
|
618
|
if (descriptor != null)
|
619
|
return getExtension(descriptor);
|
620
|
return null;
|
621
|
}
|
622
|
|
623
|
/**
|
624
|
* Search for extensions that declare the given element in their
|
625
|
* <b>triggerPoints</b> expression.
|
626
|
*
|
627
|
* @param anElement
|
628
|
* The element to use in the query
|
629
|
* @return The set of {@link INavigatorContentExtension}s that are
|
630
|
* <i>visible</i> and <i>active</i> for this content service and
|
631
|
* have a <b>triggerPoints</b> expression that is <i>enabled</i> for
|
632
|
* the given element.
|
633
|
*/
|
634
|
public Set findContentExtensionsByTriggerPoint(Object anElement) {
|
635
|
return findContentExtensionsByTriggerPoint(anElement, true, !CONSIDER_OVERRIDES);
|
636
|
}
|
637
|
|
638
|
/**
|
639
|
* Search for extensions that declare the given element in their
|
640
|
* <b>triggerPoints</b> expression.
|
641
|
*
|
642
|
* @param anElement
|
643
|
* The element to use in the query
|
644
|
* @param toLoadIfNecessary
|
645
|
* True will force the load of the extension, False will not
|
646
|
* @param computeOverrides
|
647
|
* @return The set of {@link INavigatorContentExtension}s that are
|
648
|
* <i>visible</i> and <i>active</i> for this content service and
|
649
|
* have a <b>triggerPoints</b> expression that is <i>enabled</i> for
|
650
|
* the given element.
|
651
|
*/
|
652
|
public Set findContentExtensionsByTriggerPoint(Object anElement,
|
653
|
boolean toLoadIfNecessary, boolean computeOverrides) {
|
654
|
Set enabledDescriptors = findDescriptorsByTriggerPoint(anElement, computeOverrides);
|
655
|
return extractDescriptorInstances(enabledDescriptors, toLoadIfNecessary);
|
656
|
}
|
657
|
|
658
|
/**
|
659
|
* Search for extensions that declare the given element in their
|
660
|
* <b>possibleChildren</b> expression.
|
661
|
*
|
662
|
* @param anElement
|
663
|
* The element to use in the query
|
664
|
* @return The set of {@link INavigatorContentExtension}s that are
|
665
|
* <i>visible</i> and <i>active</i> for this content service and
|
666
|
* have a <b>possibleChildren</b> expression that is <i>enabled</i>
|
667
|
* for the given element.
|
668
|
*/
|
669
|
public Set findContentExtensionsWithPossibleChild(Object anElement) {
|
670
|
return findContentExtensionsWithPossibleChild(anElement, true);
|
671
|
}
|
672
|
|
673
|
/**
|
674
|
* Search for extensions that declare the given element in their
|
675
|
* <b>possibleChildren</b> expression.
|
676
|
*
|
677
|
* @param anElement
|
678
|
* The element to use in the query
|
679
|
* @param toLoadIfNecessary
|
680
|
* True will force the load of the extension, False will not
|
681
|
* @return The set of {@link INavigatorContentExtension}s that are
|
682
|
* <i>visible</i> and <i>active</i> for this content service and
|
683
|
* have a <b>possibleChildren</b> expression that is <i>enabled</i>
|
684
|
* for the given element.
|
685
|
*/
|
686
|
public Set findContentExtensionsWithPossibleChild(Object anElement,
|
687
|
boolean toLoadIfNecessary) {
|
688
|
Set enabledDescriptors = findDescriptorsWithPossibleChild(anElement);
|
689
|
return extractDescriptorInstances(enabledDescriptors, toLoadIfNecessary);
|
690
|
}
|
691
|
|
692
|
/**
|
693
|
*
|
694
|
*
|
695
|
* @param firstClassSource
|
696
|
* @param source
|
697
|
* @param element
|
698
|
*/
|
699
|
public void rememberContribution(INavigatorContentDescriptor source,
|
700
|
INavigatorContentDescriptor firstClassSource, Object element) {
|
701
|
/*
|
702
|
* We want to write to (overwrite) the contributionMemory only if we
|
703
|
* have never heard of the element before, or if the element is coming
|
704
|
* from the same first class NCE, which means that the subsequent NCE is
|
705
|
* an override. The override will take precedence over the originally
|
706
|
* contributing NCE. However in the case of different first class NCEs,
|
707
|
* the first one wins, so we don't update the contribution memory.
|
708
|
*/
|
709
|
synchronized (this) {
|
710
|
if (contributionMemory.get(element) == null
|
711
|
|| contributionMemoryFirstClass.get(element) == firstClassSource) {
|
712
|
if (Policy.DEBUG_RESOLUTION)
|
713
|
System.out
|
714
|
.println("rememberContribution: " + Policy.getObjectString(element) + " source: " + source); //$NON-NLS-1$//$NON-NLS-2$
|
715
|
contributionMemory.put(element, source);
|
716
|
contributionMemoryFirstClass.put(element, firstClassSource);
|
717
|
}
|
718
|
}
|
719
|
}
|
720
|
|
721
|
/**
|
722
|
* Forget about the specified element
|
723
|
*
|
724
|
* @param element
|
725
|
* The element to forget.
|
726
|
*/
|
727
|
public void forgetContribution(Object element) {
|
728
|
synchronized (this) {
|
729
|
contributionMemory.remove(element);
|
730
|
contributionMemoryFirstClass.remove(element);
|
731
|
}
|
732
|
}
|
733
|
|
734
|
/**
|
735
|
* @param element
|
736
|
* @return the remembered NavigatorContentDescriptor
|
737
|
*/
|
738
|
public NavigatorContentDescriptor getContribution(Object element)
|
739
|
{
|
740
|
NavigatorContentDescriptor desc;
|
741
|
synchronized (this) {
|
742
|
desc = (NavigatorContentDescriptor) contributionMemory.get(element);
|
743
|
}
|
744
|
return desc;
|
745
|
}
|
746
|
|
747
|
/**
|
748
|
* Used only for the tests
|
749
|
* @return the size of the contribution memory
|
750
|
*/
|
751
|
public int getContributionMemorySize() {
|
752
|
synchronized (this) {
|
753
|
return contributionMemory.size();
|
754
|
}
|
755
|
}
|
756
|
|
757
|
/**
|
758
|
*
|
759
|
* @param element
|
760
|
* The element contributed by the descriptor to be returned
|
761
|
* @return The descriptor that contributed the element or null.
|
762
|
* @see #findContentExtensionsByTriggerPoint(Object)
|
763
|
*/
|
764
|
public synchronized NavigatorContentDescriptor getSourceOfContribution(Object element) {
|
765
|
if (element == null)
|
766
|
return null;
|
767
|
if (structuredViewerManager == null)
|
768
|
return null;
|
769
|
// Try here first because it might not yet be in the tree
|
770
|
NavigatorContentDescriptor src;
|
771
|
synchronized (this) {
|
772
|
src = (NavigatorContentDescriptor) contributionMemory.get(element);
|
773
|
}
|
774
|
if (src != null)
|
775
|
return src;
|
776
|
return (NavigatorContentDescriptor) structuredViewerManager.getData(element);
|
777
|
}
|
778
|
/**
|
779
|
*
|
780
|
*/
|
781
|
public static final boolean CONSIDER_OVERRIDES = true;
|
782
|
|
783
|
/**
|
784
|
* Search for extensions that declare the given element in their
|
785
|
* <b>triggerPoints</b> expression.
|
786
|
*
|
787
|
* @param anElement
|
788
|
* The element to use in the query
|
789
|
* @param considerOverrides
|
790
|
*
|
791
|
* @return The set of {@link INavigatorContentDescriptor}s that are
|
792
|
* <i>visible</i> and <i>active</i> for this content service and
|
793
|
* have a <b>triggerPoints</b> expression that is <i>enabled</i> for
|
794
|
* the given element.
|
795
|
*/
|
796
|
public Set findDescriptorsByTriggerPoint(Object anElement, boolean considerOverrides) {
|
797
|
// Here we use the cache, since objects are inserted into the
|
798
|
// cache in response to the trigger point
|
799
|
NavigatorContentDescriptor descriptor = getSourceOfContribution(anElement);
|
800
|
Set result = new TreeSet(ExtensionSequenceNumberComparator.INSTANCE);
|
801
|
if (descriptor != null) {
|
802
|
result.add(descriptor);
|
803
|
}
|
804
|
result.addAll(CONTENT_DESCRIPTOR_REGISTRY
|
805
|
.findDescriptorsForTriggerPoint(anElement, assistant, considerOverrides));
|
806
|
return result;
|
807
|
}
|
808
|
|
809
|
/**
|
810
|
* Search for extensions that declare the given element in their
|
811
|
* <b>possibleChildren</b> expression.
|
812
|
*
|
813
|
* @param anElement
|
814
|
* The element to use in the query
|
815
|
* @return The set of {@link INavigatorContentDescriptor}s that are
|
816
|
* <i>visible</i> and <i>active</i> for this content service and
|
817
|
* have a <b>possibleChildren</b> expression that is <i>enabled</i>
|
818
|
* for the given element.
|
819
|
*/
|
820
|
public Set findDescriptorsWithPossibleChild(Object anElement) {
|
821
|
return findDescriptorsWithPossibleChild(anElement, true);
|
822
|
}
|
823
|
|
824
|
/**
|
825
|
* Search for extensions that declare the given element in their
|
826
|
* <b>possibleChildren</b> expression.
|
827
|
*
|
828
|
* @param anElement
|
829
|
* The element to use in the query
|
830
|
* @param toComputeOverrides
|
831
|
* True indicates the overridden tree should be traversed.
|
832
|
* @return The set of {@link INavigatorContentDescriptor}s that are
|
833
|
* <i>visible</i> and <i>active</i> for this content service and
|
834
|
* have a <b>possibleChildren</b> expression that is <i>enabled</i>
|
835
|
* for the given element.
|
836
|
*/
|
837
|
public Set findDescriptorsWithPossibleChild(Object anElement,
|
838
|
boolean toComputeOverrides) {
|
839
|
// Don't use the cache which is only used for triggerPoints
|
840
|
Set result = new TreeSet(ExtensionSequenceNumberComparator.INSTANCE);
|
841
|
result.addAll(CONTENT_DESCRIPTOR_REGISTRY
|
842
|
.findDescriptorsForPossibleChild(anElement, assistant,
|
843
|
toComputeOverrides));
|
844
|
return result;
|
845
|
}
|
846
|
|
847
|
/*
|
848
|
* (non-Javadoc)
|
849
|
*
|
850
|
* @seeorg.eclipse.ui.internal.navigator.INavigatorContentService#
|
851
|
* onExtensionActivation(java.lang.String, java.lang.String, boolean)
|
852
|
*/
|
853
|
public void onExtensionActivation(String aViewerId,
|
854
|
String[] aNavigatorExtensionId, boolean toEnable) {
|
855
|
synchronized (this) {
|
856
|
SafeRunner.run(new NavigatorSafeRunnable() {
|
857
|
public void run() throws Exception {
|
858
|
NavigatorContentDescriptor key;
|
859
|
NavigatorContentExtension extension;
|
860
|
for (Iterator iter = contentExtensions.keySet().iterator(); iter
|
861
|
.hasNext();) {
|
862
|
key = (NavigatorContentDescriptor) iter.next();
|
863
|
INavigatorActivationService activation = getActivationService();
|
864
|
if (!activation.isNavigatorExtensionActive(key.getId())) {
|
865
|
extension = (NavigatorContentExtension) contentExtensions
|
866
|
.get(key);
|
867
|
iter.remove();
|
868
|
extension.dispose();
|
869
|
}
|
870
|
}
|
871
|
}
|
872
|
});
|
873
|
}
|
874
|
if (structuredViewerManager != null) {
|
875
|
structuredViewerManager.resetViewerData();
|
876
|
}
|
877
|
update();
|
878
|
}
|
879
|
|
880
|
/*
|
881
|
* (non-Javadoc)
|
882
|
*
|
883
|
* @see org.eclipse.ui.internal.navigator.INavigatorContentService#update()
|
884
|
*/
|
885
|
public void update() {
|
886
|
rootContentProviders = null;
|
887
|
if (structuredViewerManager != null) {
|
888
|
structuredViewerManager.safeRefresh();
|
889
|
}
|
890
|
}
|
891
|
|
892
|
/*
|
893
|
* (non-Javadoc)
|
894
|
*
|
895
|
* @see
|
896
|
* org.eclipse.ui.internal.navigator.INavigatorContentService#getViewerId()
|
897
|
*/
|
898
|
public final String getViewerId() {
|
899
|
return viewerDescriptor.getViewerId();
|
900
|
}
|
901
|
|
902
|
/**
|
903
|
* Returns the remembered data (the NavigatorContentDescriptor) associated with
|
904
|
* an object in the viewer. This can be used to test an object's presence in the viewer.
|
905
|
* @param element
|
906
|
* @return the object stored as data in the viewer
|
907
|
*/
|
908
|
public Object getViewerElementData(Object element) {
|
909
|
if (structuredViewerManager != null) {
|
910
|
return structuredViewerManager.getData(element);
|
911
|
}
|
912
|
return null;
|
913
|
}
|
914
|
|
915
|
/**
|
916
|
*
|
917
|
* @param aDescriptorKey
|
918
|
* A descriptor
|
919
|
* @return The cached NavigatorContentExtension from the descriptor
|
920
|
*/
|
921
|
public final NavigatorContentExtension getExtension(
|
922
|
INavigatorContentDescriptor aDescriptorKey) {
|
923
|
return getExtension(aDescriptorKey, true);
|
924
|
}
|
925
|
|
926
|
/**
|
927
|
*
|
928
|
* @param aDescriptorKey
|
929
|
* @param toLoadIfNecessary
|
930
|
* True if the extension should be loaded if it is not already.
|
931
|
* @return The instance of the extension for the given descriptor key.
|
932
|
*/
|
933
|
public final NavigatorContentExtension getExtension(
|
934
|
INavigatorContentDescriptor aDescriptorKey,
|
935
|
boolean toLoadIfNecessary) {
|
936
|
/* Query and return the relevant descriptor instance */
|
937
|
NavigatorContentExtension extension = (NavigatorContentExtension) contentExtensions
|
938
|
.get(aDescriptorKey);
|
939
|
if (extension != null || !toLoadIfNecessary) {
|
940
|
return extension;
|
941
|
}
|
942
|
|
943
|
/*
|
944
|
* If the descriptor instance hasn't been created yet, then we need to
|
945
|
* (1) verify that it wasn't added by another thread, (2) create and add
|
946
|
* the result into the map
|
947
|
*/
|
948
|
synchronized (this) {
|
949
|
extension = (NavigatorContentExtension) contentExtensions
|
950
|
.get(aDescriptorKey);
|
951
|
if (extension == null) {
|
952
|
contentExtensions.put(aDescriptorKey,
|
953
|
(extension = new NavigatorContentExtension(
|
954
|
(NavigatorContentDescriptor) aDescriptorKey,
|
955
|
this, structuredViewerManager)));
|
956
|
notifyListeners(extension);
|
957
|
}
|
958
|
}
|
959
|
return extension;
|
960
|
|
961
|
}
|
962
|
|
963
|
/*
|
964
|
* (non-Javadoc)
|
965
|
*
|
966
|
* @seeorg.eclipse.ui.internal.navigator.INavigatorContentService#
|
967
|
* getViewerDescriptor()
|
968
|
*/
|
969
|
public INavigatorViewerDescriptor getViewerDescriptor() {
|
970
|
return viewerDescriptor;
|
971
|
}
|
972
|
|
973
|
/*
|
974
|
* (non-Javadoc)
|
975
|
*
|
976
|
* @see
|
977
|
* org.eclipse.ui.internal.navigator.INavigatorContentService#restoreState
|
978
|
* (org.eclipse.ui.IMemento)
|
979
|
*/
|
980
|
public void restoreState(final IMemento aMemento) {
|
981
|
synchronized (this) {
|
982
|
for (Iterator extensionItr = getExtensions().iterator(); extensionItr.hasNext();) {
|
983
|
final NavigatorContentExtension element = (NavigatorContentExtension) extensionItr
|
984
|
.next();
|
985
|
SafeRunner.run(new NavigatorSafeRunnable(((NavigatorContentDescriptor) element
|
986
|
.getDescriptor()).getConfigElement()) {
|
987
|
public void run() throws Exception {
|
988
|
element.restoreState(aMemento);
|
989
|
}
|
990
|
});
|
991
|
}
|
992
|
}
|
993
|
}
|
994
|
|
995
|
/*
|
996
|
* (non-Javadoc)
|
997
|
*
|
998
|
* @see
|
999
|
* org.eclipse.ui.internal.navigator.INavigatorContentService#saveState(
|
1000
|
* org.eclipse.ui.IMemento)
|
1001
|
*/
|
1002
|
public void saveState(final IMemento aMemento) {
|
1003
|
synchronized (this) {
|
1004
|
for (Iterator extensionItr = getExtensions().iterator(); extensionItr.hasNext();) {
|
1005
|
final NavigatorContentExtension element = (NavigatorContentExtension) extensionItr
|
1006
|
.next();
|
1007
|
SafeRunner.run(new NavigatorSafeRunnable(((NavigatorContentDescriptor) element
|
1008
|
.getDescriptor()).getConfigElement()) {
|
1009
|
public void run() throws Exception {
|
1010
|
element.saveState(aMemento);
|
1011
|
}
|
1012
|
});
|
1013
|
}
|
1014
|
}
|
1015
|
}
|
1016
|
|
1017
|
public boolean isActive(String anExtensionId) {
|
1018
|
return assistant.isActive(anExtensionId);
|
1019
|
}
|
1020
|
|
1021
|
public boolean isVisible(String anExtensionId) {
|
1022
|
return assistant.isVisible(anExtensionId);
|
1023
|
}
|
1024
|
|
1025
|
protected final Collection getExtensions() {
|
1026
|
return (contentExtensions.size() > 0) ? Collections
|
1027
|
.unmodifiableCollection(contentExtensions.values())
|
1028
|
: Collections.EMPTY_LIST;
|
1029
|
}
|
1030
|
|
1031
|
/*
|
1032
|
* (non-Javadoc)
|
1033
|
*
|
1034
|
* @see
|
1035
|
* org.eclipse.ui.internal.navigator.INavigatorContentService#addListener
|
1036
|
* (org
|
1037
|
* .eclipse.ui.internal.navigator.extensions.INavigatorContentServiceListener
|
1038
|
* )
|
1039
|
*/
|
1040
|
public void addListener(INavigatorContentServiceListener aListener) {
|
1041
|
listeners.add(aListener);
|
1042
|
}
|
1043
|
|
1044
|
/*
|
1045
|
* (non-Javadoc)
|
1046
|
*
|
1047
|
* @see org.eclipse.ui.navigator.INavigatorContentService#getFilterService()
|
1048
|
*/
|
1049
|
public INavigatorFilterService getFilterService() {
|
1050
|
if (navigatorFilterService == null) {
|
1051
|
navigatorFilterService = new NavigatorFilterService(this);
|
1052
|
}
|
1053
|
return navigatorFilterService;
|
1054
|
}
|
1055
|
|
1056
|
/*
|
1057
|
* (non-Javadoc)
|
1058
|
*
|
1059
|
* @see org.eclipse.ui.navigator.INavigatorContentService#getFilterService()
|
1060
|
*/
|
1061
|
public INavigatorSorterService getSorterService() {
|
1062
|
if (navigatorSorterService == null) {
|
1063
|
navigatorSorterService = new NavigatorSorterService(this);
|
1064
|
assistant.addListener(navigatorSorterService);
|
1065
|
}
|
1066
|
return navigatorSorterService;
|
1067
|
}
|
1068
|
|
1069
|
/*
|
1070
|
* (non-Javadoc)
|
1071
|
*
|
1072
|
* @see org.eclipse.ui.navigator.INavigatorContentService#getFilterService()
|
1073
|
*/
|
1074
|
public INavigatorPipelineService getPipelineService() {
|
1075
|
if (navigatorPipelineService == null) {
|
1076
|
navigatorPipelineService = new NavigatorPipelineService(this);
|
1077
|
}
|
1078
|
return navigatorPipelineService;
|
1079
|
}
|
1080
|
|
1081
|
/*
|
1082
|
* (non-Javadoc)
|
1083
|
*
|
1084
|
* @see org.eclipse.ui.navigator.INavigatorContentService#getDnDService()
|
1085
|
*/
|
1086
|
public INavigatorDnDService getDnDService() {
|
1087
|
if (navigatorDnDService == null) {
|
1088
|
navigatorDnDService = new NavigatorDnDService(this);
|
1089
|
}
|
1090
|
return navigatorDnDService;
|
1091
|
}
|
1092
|
|
1093
|
/*
|
1094
|
* (non-Javadoc)
|
1095
|
*
|
1096
|
* @see
|
1097
|
* org.eclipse.ui.navigator.INavigatorContentService#getActivationService()
|
1098
|
*/
|
1099
|
public INavigatorActivationService getActivationService() {
|
1100
|
|
1101
|
if (navigatorActivationService == null) {
|
1102
|
navigatorActivationService = new NavigatorActivationService(this);
|
1103
|
}
|
1104
|
return navigatorActivationService;
|
1105
|
}
|
1106
|
|
1107
|
/*
|
1108
|
* (non-Javadoc)
|
1109
|
*
|
1110
|
* @see
|
1111
|
* org.eclipse.ui.navigator.INavigatorContentService#getSaveableService()
|
1112
|
*/
|
1113
|
public INavigatorSaveablesService getSaveablesService() {
|
1114
|
synchronized (this) {
|
1115
|
if (navigatorSaveablesService == null) {
|
1116
|
navigatorSaveablesService = new NavigatorSaveablesService(this);
|
1117
|
assistant.addListener(navigatorSaveablesService);
|
1118
|
}
|
1119
|
return navigatorSaveablesService;
|
1120
|
}
|
1121
|
}
|
1122
|
|
1123
|
/**
|
1124
|
* Not API as of 3.3.
|
1125
|
*
|
1126
|
* @return The extension state service for this content service.
|
1127
|
*
|
1128
|
*/
|
1129
|
public NavigatorExtensionStateService getExtensionStateService() {
|
1130
|
if (navigatorExtensionStateService == null) {
|
1131
|
navigatorExtensionStateService = new NavigatorExtensionStateService(
|
1132
|
this);
|
1133
|
}
|
1134
|
return navigatorExtensionStateService;
|
1135
|
}
|
1136
|
|
1137
|
/**
|
1138
|
* Non-API method to return a shell.
|
1139
|
*
|
1140
|
* @return A shell associated with the current viewer (if any) or
|
1141
|
* <b>null</b>.
|
1142
|
*/
|
1143
|
public Shell getShell() {
|
1144
|
if (structuredViewerManager != null
|
1145
|
&& structuredViewerManager.getViewer() != null) {
|
1146
|
return structuredViewerManager.getViewer().getControl().getShell();
|
1147
|
}
|
1148
|
return null;
|
1149
|
}
|
1150
|
|
1151
|
protected boolean isRootExtension(String anExtensionId) {
|
1152
|
return assistant.isRootExtension(anExtensionId);
|
1153
|
}
|
1154
|
|
1155
|
/*
|
1156
|
* (non-Javadoc)
|
1157
|
*
|
1158
|
* @see
|
1159
|
* org.eclipse.ui.internal.navigator.INavigatorContentService#removeListener
|
1160
|
* (
|
1161
|
* org.eclipse.ui.internal.navigator.extensions.INavigatorContentServiceListener
|
1162
|
* )
|
1163
|
*/
|
1164
|
public void removeListener(INavigatorContentServiceListener aListener) {
|
1165
|
listeners.remove(aListener);
|
1166
|
}
|
1167
|
|
1168
|
/*
|
1169
|
* (non-Javadoc)
|
1170
|
*
|
1171
|
* @see java.lang.Object#toString()
|
1172
|
*/
|
1173
|
public String toString() {
|
1174
|
return "ContentService[" + viewerDescriptor.getViewerId() + "]"; //$NON-NLS-1$//$NON-NLS-2$
|
1175
|
}
|
1176
|
|
1177
|
private void notifyListeners(final NavigatorContentExtension aDescriptorInstance) {
|
1178
|
|
1179
|
if (listeners.size() == 0) {
|
1180
|
return;
|
1181
|
}
|
1182
|
|
1183
|
final List failedListeners = new ArrayList();
|
1184
|
|
1185
|
for (Iterator listenersItr = listeners.iterator(); listenersItr.hasNext();) {
|
1186
|
final INavigatorContentServiceListener listener = (INavigatorContentServiceListener) listenersItr
|
1187
|
.next();
|
1188
|
SafeRunner.run(new NavigatorSafeRunnable() {
|
1189
|
|
1190
|
public void run() throws Exception {
|
1191
|
listener.onLoad(aDescriptorInstance);
|
1192
|
}
|
1193
|
|
1194
|
public void handleException(Throwable e) {
|
1195
|
super.handleException(e);
|
1196
|
failedListeners.add(listener);
|
1197
|
}
|
1198
|
});
|
1199
|
}
|
1200
|
|
1201
|
if (failedListeners.size() > 0) {
|
1202
|
listeners.removeAll(failedListeners);
|
1203
|
}
|
1204
|
}
|
1205
|
|
1206
|
private ITreeContentProvider[] extractContentProviders(
|
1207
|
Set theDescriptorInstances) {
|
1208
|
if (theDescriptorInstances.size() == 0) {
|
1209
|
return NO_CONTENT_PROVIDERS;
|
1210
|
}
|
1211
|
List resultProvidersList = new ArrayList();
|
1212
|
for (Iterator itr = theDescriptorInstances.iterator(); itr.hasNext();) {
|
1213
|
resultProvidersList.add(((NavigatorContentExtension) itr.next())
|
1214
|
.internalGetContentProvider());
|
1215
|
}
|
1216
|
return (ITreeContentProvider[]) resultProvidersList
|
1217
|
.toArray(new ITreeContentProvider[resultProvidersList.size()]);
|
1218
|
}
|
1219
|
|
1220
|
private Set extractDescriptorInstances(Set theDescriptors,
|
1221
|
boolean toLoadAllIfNecessary) {
|
1222
|
if (theDescriptors.size() == 0) {
|
1223
|
return Collections.EMPTY_SET;
|
1224
|
}
|
1225
|
Set resultInstances = new TreeSet(ExtensionSequenceNumberComparator.INSTANCE);
|
1226
|
for (Iterator descriptorIter = theDescriptors.iterator(); descriptorIter
|
1227
|
.hasNext();) {
|
1228
|
NavigatorContentExtension extension = getExtension(
|
1229
|
(NavigatorContentDescriptor) descriptorIter.next(),
|
1230
|
toLoadAllIfNecessary);
|
1231
|
if (extension != null) {
|
1232
|
resultInstances.add(extension);
|
1233
|
|
1234
|
}
|
1235
|
}
|
1236
|
return resultInstances;
|
1237
|
}
|
1238
|
|
1239
|
/**
|
1240
|
* @return the viewer
|
1241
|
*/
|
1242
|
public Viewer getViewer() {
|
1243
|
return structuredViewerManager.getViewer();
|
1244
|
}
|
1245
|
|
1246
|
|
1247
|
/**
|
1248
|
* Get our preferences
|
1249
|
*/
|
1250
|
static IEclipsePreferences getPreferencesRoot() {
|
1251
|
IEclipsePreferences root = (IEclipsePreferences) Platform.getPreferencesService().getRootNode().node(
|
1252
|
InstanceScope.SCOPE);
|
1253
|
return (IEclipsePreferences) root.node(NavigatorPlugin.PLUGIN_ID);
|
1254
|
}
|
1255
|
|
1256
|
|
1257
|
static void flushPreferences(IEclipsePreferences prefs) {
|
1258
|
try {
|
1259
|
prefs.flush();
|
1260
|
} catch (BackingStoreException e) {
|
1261
|
IStatus status = new Status(IStatus.ERROR, Platform.PI_RUNTIME, IStatus.ERROR,
|
1262
|
CommonNavigatorMessages.NavigatorContentService_problemSavingPreferences, e);
|
1263
|
Platform.getLog(Platform.getBundle(NavigatorPlugin.PLUGIN_ID)).log(status);
|
1264
|
}
|
1265
|
}
|
1266
|
|
1267
|
}
|