KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > navigator > NavigatorContentService


1 /*******************************************************************************
2  * Copyright (c) 2003, 2007 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  *******************************************************************************/

11 package org.eclipse.ui.internal.navigator;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collection JavaDoc;
15 import java.util.Collections JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.HashSet JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.List JavaDoc;
20 import java.util.Map JavaDoc;
21 import java.util.Set JavaDoc;
22 import java.util.SortedSet JavaDoc;
23 import java.util.TreeSet JavaDoc;
24 import java.util.WeakHashMap JavaDoc;
25
26 import org.eclipse.core.runtime.ISafeRunnable;
27 import org.eclipse.core.runtime.SafeRunner;
28 import org.eclipse.jface.viewers.ILabelProvider;
29 import org.eclipse.jface.viewers.ITreeContentProvider;
30 import org.eclipse.jface.viewers.StructuredViewer;
31 import org.eclipse.jface.viewers.Viewer;
32 import org.eclipse.swt.widgets.Shell;
33 import org.eclipse.ui.IMemento;
34 import org.eclipse.ui.internal.navigator.dnd.NavigatorDnDService;
35 import org.eclipse.ui.internal.navigator.extensions.ExtensionPriorityComparator;
36 import org.eclipse.ui.internal.navigator.extensions.NavigatorContentDescriptor;
37 import org.eclipse.ui.internal.navigator.extensions.NavigatorContentDescriptorManager;
38 import org.eclipse.ui.internal.navigator.extensions.NavigatorContentExtension;
39 import org.eclipse.ui.internal.navigator.extensions.NavigatorViewerDescriptor;
40 import org.eclipse.ui.internal.navigator.extensions.NavigatorViewerDescriptorManager;
41 import org.eclipse.ui.internal.navigator.extensions.StructuredViewerManager;
42 import org.eclipse.ui.internal.navigator.sorters.NavigatorSorterService;
43 import org.eclipse.ui.navigator.IDescriptionProvider;
44 import org.eclipse.ui.navigator.IExtensionActivationListener;
45 import org.eclipse.ui.navigator.IExtensionStateModel;
46 import org.eclipse.ui.navigator.IMementoAware;
47 import org.eclipse.ui.navigator.INavigatorActivationService;
48 import org.eclipse.ui.navigator.INavigatorContentDescriptor;
49 import org.eclipse.ui.navigator.INavigatorContentExtension;
50 import org.eclipse.ui.navigator.INavigatorContentService;
51 import org.eclipse.ui.navigator.INavigatorContentServiceListener;
52 import org.eclipse.ui.navigator.INavigatorDnDService;
53 import org.eclipse.ui.navigator.INavigatorFilterService;
54 import org.eclipse.ui.navigator.INavigatorPipelineService;
55 import org.eclipse.ui.navigator.INavigatorSaveablesService;
56 import org.eclipse.ui.navigator.INavigatorSorterService;
57 import org.eclipse.ui.navigator.INavigatorViewerDescriptor;
58
59 /**
60  * <p>
61  * Provides centralized access to the information provided by
62  * NavigatorContentExtensions. Can be instantiated as needed, but should be
63  * cached for active viewers. Information specific to a given viewer will be
64  * cached by the NavigatorContentService, not including ContentProviders and
65  * Label Providers created by {@link #createCommonContentProvider()}and
66  * {@link #createCommonLabelProvider()}respectively.
67  * </p>
68  *
69  * <p>
70  * The following class is experimental until fully documented.
71  * </p>
72  */

73 public class NavigatorContentService implements IExtensionActivationListener,
74         IMementoAware, INavigatorContentService {
75
76     private static final NavigatorContentDescriptorManager CONTENT_DESCRIPTOR_REGISTRY = NavigatorContentDescriptorManager
77             .getInstance();
78
79     private static final NavigatorViewerDescriptorManager VIEWER_DESCRIPTOR_REGISTRY = NavigatorViewerDescriptorManager
80             .getInstance();
81
82     private static final ITreeContentProvider[] NO_CONTENT_PROVIDERS = new ITreeContentProvider[0];
83
84     private static final ILabelProvider[] NO_LABEL_PROVIDERS = new ILabelProvider[0];
85
86     private static final INavigatorContentDescriptor[] NO_DESCRIPTORS = new INavigatorContentDescriptor[0];
87
88     private static final String JavaDoc[] NO_EXTENSION_IDS = new String JavaDoc[0];
89
90     private final NavigatorViewerDescriptor viewerDescriptor;
91
92     private final List JavaDoc listeners = new ArrayList JavaDoc();
93
94     /*
95      * A map of (String-based-Navigator-Content-Extension-IDs,
96      * NavigatorContentExtension-objects)-pairs
97      */

98     private final Map JavaDoc contentExtensions = new HashMap JavaDoc();
99
100     private StructuredViewerManager structuredViewerManager;
101
102     private ITreeContentProvider[] rootContentProviders;
103
104     private WeakHashMap JavaDoc contributionMemory;
105
106     private ITreeContentProvider contentProvider;
107
108     private ILabelProvider labelProvider;
109
110     private final VisibilityAssistant assistant;
111
112     private NavigatorFilterService navigatorFilterService;
113
114     private INavigatorSorterService navigatorSorterService;
115
116     private INavigatorPipelineService navigatorPipelineService;
117
118     private INavigatorDnDService navigatorDnDService;
119
120     private INavigatorActivationService navigatorActivationService;
121
122     private NavigatorSaveablesService navigatorSaveablesService;
123
124     private NavigatorExtensionStateService navigatorExtensionStateService;
125
126     private IDescriptionProvider descriptionProvider;
127
128     private boolean contentProviderInitialized;
129
130     private boolean labelProviderInitialized;
131
132     /**
133      * @param aViewerId
134      * The viewer id for this content service; normally from the
135      * <b>org.eclipse.ui.views</b> extension.
136      */

137     public NavigatorContentService(String JavaDoc aViewerId) {
138         super();
139         aViewerId = aViewerId != null ? aViewerId : ""; //$NON-NLS-1$
140
viewerDescriptor = VIEWER_DESCRIPTOR_REGISTRY
141                 .getNavigatorViewerDescriptor(aViewerId);
142         assistant = new VisibilityAssistant(viewerDescriptor,
143                 getActivationService());
144         getActivationService().addExtensionActivationListener(this);
145     }
146
147     /**
148      * @param aViewerId
149      * The viewer id for this content service; normally from the
150      * <b>org.eclipse.ui.views</b> extension.
151      * @param aViewer
152      * The viewer that this content service will be associated with.
153      */

154     public NavigatorContentService(String JavaDoc aViewerId, StructuredViewer aViewer) {
155         this(aViewerId);
156         structuredViewerManager = new StructuredViewerManager(aViewer);
157     }
158
159     public String JavaDoc[] getVisibleExtensionIds() {
160
161         List JavaDoc visibleExtensionIds = new ArrayList JavaDoc();
162
163         NavigatorContentDescriptor[] descriptors = CONTENT_DESCRIPTOR_REGISTRY
164                 .getAllContentDescriptors();
165         for (int i = 0; i < descriptors.length; i++) {
166             if (assistant.isVisible(descriptors[i].getId())) {
167                 visibleExtensionIds.add(descriptors[i].getId());
168             }
169         }
170         if (visibleExtensionIds.isEmpty()) {
171             return NO_EXTENSION_IDS;
172         }
173         return (String JavaDoc[]) visibleExtensionIds
174                 .toArray(new String JavaDoc[visibleExtensionIds.size()]);
175
176     }
177
178     public INavigatorContentDescriptor[] getVisibleExtensions() {
179         List JavaDoc visibleDescriptors = new ArrayList JavaDoc();
180
181         NavigatorContentDescriptor[] descriptors = CONTENT_DESCRIPTOR_REGISTRY
182                 .getAllContentDescriptors();
183         for (int i = 0; i < descriptors.length; i++) {
184             if (assistant.isVisible(descriptors[i].getId())) {
185                 visibleDescriptors.add(descriptors[i]);
186             }
187         }
188         if (visibleDescriptors.isEmpty()) {
189             return NO_DESCRIPTORS;
190         }
191         return (INavigatorContentDescriptor[]) visibleDescriptors
192                 .toArray(new INavigatorContentDescriptor[visibleDescriptors
193                         .size()]);
194
195     }
196
197     /* package */INavigatorContentDescriptor[] getActiveDescriptorsWithSaveables() {
198         List JavaDoc result = new ArrayList JavaDoc();
199
200         NavigatorContentDescriptor[] descriptors = CONTENT_DESCRIPTOR_REGISTRY
201                 .getContentDescriptorsWithSaveables();
202         for (int i = 0; i < descriptors.length; i++) {
203             if (assistant.isVisible(descriptors[i].getId())
204                     && assistant.isActive(descriptors[i])) {
205                 result.add(descriptors[i]);
206             }
207         }
208         if (result.isEmpty()) {
209             return NO_DESCRIPTORS;
210         }
211         return (INavigatorContentDescriptor[]) result
212                 .toArray(new INavigatorContentDescriptor[result.size()]);
213
214     }
215
216     /*
217      * (non-Javadoc)
218      *
219      * @see org.eclipse.ui.navigator.INavigatorContentService#bindExtensions(java.lang.String[],
220      * boolean)
221      */

222     public INavigatorContentDescriptor[] bindExtensions(String JavaDoc[] extensionIds,
223             boolean isRoot) {
224         if (extensionIds == null || extensionIds.length == 0) {
225             return NO_DESCRIPTORS;
226         }
227
228         for (int i = 0; i < extensionIds.length; i++) {
229             assistant.bindExtensions(extensionIds, isRoot);
230         }
231         Set JavaDoc boundDescriptors = new HashSet JavaDoc();
232         INavigatorContentDescriptor descriptor;
233         for (int i = 0; i < extensionIds.length; i++) {
234             descriptor = CONTENT_DESCRIPTOR_REGISTRY
235                     .getContentDescriptor(extensionIds[i]);
236             if (descriptor != null) {
237                 boundDescriptors.add(descriptor);
238             }
239         }
240
241         if (boundDescriptors.size() == 0) {
242             return NO_DESCRIPTORS;
243         }
244         return (INavigatorContentDescriptor[]) boundDescriptors
245                 .toArray(new INavigatorContentDescriptor[boundDescriptors
246                         .size()]);
247
248     }
249
250     /*
251      * (non-Javadoc)
252      *
253      * @see org.eclipse.ui.internal.navigator.INavigatorContentService#createCommonContentProvider()
254      */

255     public ITreeContentProvider createCommonContentProvider() {
256         if (contentProviderInitialized) {
257             return contentProvider;
258         }
259         synchronized (this) {
260             if (contentProvider == null) {
261                 contentProvider = new NavigatorContentServiceContentProvider(
262                         this);
263             }
264             contentProviderInitialized = true;
265         }
266         return contentProvider;
267     }
268
269     /*
270      * (non-Javadoc)
271      *
272      * @see org.eclipse.ui.internal.navigator.INavigatorContentService#createCommonLabelProvider()
273      */

274     public ILabelProvider createCommonLabelProvider() {
275         if (labelProviderInitialized) {
276             return labelProvider;
277         }
278         synchronized (this) {
279             if (labelProvider == null) {
280                 labelProvider = new NavigatorContentServiceLabelProvider(this);
281             }
282             labelProviderInitialized = true;
283         }
284         return labelProvider;
285     }
286
287     /*
288      * (non-Javadoc)
289      *
290      * @see org.eclipse.ui.navigator.INavigatorContentService#createCommonDescriptionProvider()
291      */

292     public IDescriptionProvider createCommonDescriptionProvider() {
293         if (descriptionProvider != null) {
294             return descriptionProvider;
295         }
296         synchronized (this) {
297             if (descriptionProvider == null) {
298                 descriptionProvider = new NavigatorContentServiceDescriptionProvider(
299                         this);
300             }
301         }
302         return descriptionProvider;
303     }
304
305     /*
306      * (non-Javadoc)
307      *
308      * @see org.eclipse.ui.internal.navigator.INavigatorContentService#dispose()
309      */

310     public void dispose() {
311         if (navigatorSaveablesService != null) {
312             assistant.removeListener(navigatorSaveablesService);
313         }
314         for (Iterator JavaDoc contentItr = contentExtensions.values().iterator(); contentItr
315                 .hasNext();) {
316             ((NavigatorContentExtension) contentItr.next()).dispose();
317         }
318         getActivationService().removeExtensionActivationListener(this);
319         assistant.dispose();
320     }
321
322     protected void updateService(Viewer aViewer, Object JavaDoc anOldInput,
323             Object JavaDoc aNewInput) {
324
325         synchronized (this) {
326
327             if (structuredViewerManager == null) {
328                 structuredViewerManager = new StructuredViewerManager(aViewer);
329                 structuredViewerManager.inputChanged(anOldInput, aNewInput);
330             } else {
331                 structuredViewerManager.inputChanged(aViewer, anOldInput,
332                         aNewInput);
333             }
334
335             for (Iterator JavaDoc contentItr = contentExtensions.values().iterator(); contentItr
336                     .hasNext();) {
337                 structuredViewerManager
338                         .initialize(((NavigatorContentExtension) contentItr
339                                 .next()).getContentProvider());
340             }
341
342             rootContentProviders = extractContentProviders(findRootContentExtensions(aNewInput));
343         }
344     }
345
346     public IExtensionStateModel findStateModel(String JavaDoc anExtensionId) {
347         if (anExtensionId == null) {
348             return null;
349         }
350         INavigatorContentDescriptor desc = CONTENT_DESCRIPTOR_REGISTRY
351                 .getContentDescriptor(anExtensionId);
352         if (desc == null) {
353             return null;
354         }
355         INavigatorContentExtension ext = getExtension(desc);
356         if (ext == null) {
357             return null;
358         }
359         return ext.getStateModel();
360     }
361
362     /**
363      * Return a set of content providers that could provide a parent for the
364      * given element. These content extensions are determined by consulting the
365      * <b>possibleChildren</b> expression in the <b>navigatorContent</b>
366      * extension.
367      *
368      * <p>
369      * Clients that wish to tap into the link with editor support must describe
370      * all of their possible children in their <b>possibleChildren</b>
371      * expressions.
372      * </p>
373      *
374      * @param anElement
375      * An element from the tree (generally from a setSelection()
376      * method).
377      * @return The set of content providers that may be able to provide a
378      * parent.
379      */

380     public ITreeContentProvider[] findParentContentProviders(Object JavaDoc anElement) {
381         return extractContentProviders(findContentExtensionsWithPossibleChild(anElement));
382     }
383
384     /**
385      * <p>
386      * Return all of the content providers that are relevant for the viewer. The
387      * viewer is determined by the ID used to create the
388      * INavigatorContentService ({@link #getViewerId() }). See
389      * {@link #createCommonContentProvider() } for more information about how
390      * content providers are located for the root of the viewer. The root
391      * content providers are calculated once. If a new element is supplied, a
392      * client must call {@link #update() } prior in order to reset the
393      * calculated root providers.
394      * </p>
395      *
396      * @param anElement
397      * An element from the tree (generally the input of the viewer)
398      * @return The set of content providers that can provide root elements for a
399      * viewer.
400      */

401     public ITreeContentProvider[] findRootContentProviders(Object JavaDoc anElement) {
402         if (rootContentProviders != null) {
403             return rootContentProviders;
404         }
405         synchronized (this) {
406             if (rootContentProviders == null) {
407                 rootContentProviders = extractContentProviders(findRootContentExtensions(anElement));
408
409             }
410         }
411         return rootContentProviders;
412     }
413
414     /**
415      *
416      * Return all of the label providers that are enabled for the given element.
417      * A label provider is 'enabled' if its corresponding content provider
418      * returned the element, or the element is described in the content
419      * extension's <b>triggerPoints</b> expression.
420      *
421      * @param anElement
422      * An element from the tree (any element contributed to the
423      * tree).
424      * @return The set of label providers that may be able to provide a valid
425      * (non-null) label.
426      */

427     public ILabelProvider[] findRelevantLabelProviders(Object JavaDoc anElement) {
428         return extractLabelProviders(findContentExtensionsWithPossibleChild(
429                 anElement, false));
430     }
431
432     /**
433      * Search for extensions that declare the given element in their
434      * <b>triggerPoints</b> expression.
435      *
436      * @param anElement
437      * The element to use in the query
438      * @return The set of {@link INavigatorContentExtension}s that are
439      * <i>visible</i> and <i>active</i> for this content service and
440      * either declared through a
441      * <b>org.eclipse.ui.navigator.viewer/viewerContentBinding</b> to
442      * be a root element or have a <b>triggerPoints</b> expression that
443      * is <i>enabled</i> for the given element.
444      */

445     public Set JavaDoc findRootContentExtensions(Object JavaDoc anElement) {
446         return findRootContentExtensions(anElement, true);
447     }
448
449     /**
450      * Search for extensions that declare the given element in their
451      * <b>triggerPoints</b> expression.
452      *
453      * @param anElement
454      * The element to use in the query
455      * @param toRespectViewerRoots
456      * True respect the <b>viewerContentBinding</b>s, False will
457      * look only for matching <b>triggerPoints</b> expressions.
458      * @return The set of {@link INavigatorContentExtension}s that are
459      * <i>visible</i> and <i>active</i> for this content service and
460      * either declared through a
461      * <b>org.eclipse.ui.navigator.viewer/viewerContentBinding</b> to
462      * be a root element or have a <b>triggerPoints</b> expression that
463      * is <i>enabled</i> for the given element.
464      */

465     public Set JavaDoc findRootContentExtensions(Object JavaDoc anElement,
466             boolean toRespectViewerRoots) {
467
468         SortedSet JavaDoc rootExtensions = new TreeSet JavaDoc(
469                 ExtensionPriorityComparator.INSTANCE);
470         if (toRespectViewerRoots
471                 && viewerDescriptor.hasOverriddenRootExtensions()) {
472
473             NavigatorContentDescriptor[] descriptors = CONTENT_DESCRIPTOR_REGISTRY
474                     .getAllContentDescriptors();
475
476             NavigatorContentExtension extension = null;
477             for (int i = 0; i < descriptors.length; i++) {
478                 if (isActive(descriptors[i].getId())
479                         && isRootExtension(descriptors[i].getId())) {
480                     extension = getExtension(descriptors[i]);
481                     if (!extension.hasLoadingFailed()) {
482                         rootExtensions.add(extension);
483                     }
484                 }
485             }
486         }
487         if (rootExtensions.isEmpty()) {
488             return findContentExtensionsByTriggerPoint(anElement);
489         }
490         return rootExtensions;
491     }
492
493     /**
494      * Search for extensions that declare the given element in their
495      * <b>possibleChildren</b> expression.
496      *
497      * @param anElement
498      * The element to use in the query
499      * @return The set of {@link INavigatorContentExtension}s that are
500      * <i>visible</i> and <i>active</i> for this content service and
501      * have a <b>possibleChildren</b> expression that is <i>enabled</i>
502      * for the given element.
503      */

504     public Set JavaDoc findOverrideableContentExtensionsByTriggerPoint(Object JavaDoc anElement) {
505         Set JavaDoc overrideableExtensions = new TreeSet JavaDoc(
506                 ExtensionPriorityComparator.INSTANCE);
507         Set JavaDoc descriptors = findDescriptorsByTriggerPoint(anElement);
508         for (Iterator JavaDoc iter = descriptors.iterator(); iter.hasNext();) {
509             INavigatorContentDescriptor descriptor = (INavigatorContentDescriptor) iter
510                     .next();
511             if (descriptor.hasOverridingExtensions()) {
512                 overrideableExtensions.add(getExtension(descriptor));
513             }
514         }
515         return overrideableExtensions;
516     }
517
518     /**
519      * Search for extensions that declare the given element in their
520      * <b>possibleChildren</b> expression.
521      *
522      * @param anElement
523      * The element to use in the query
524      * @return The set of {@link INavigatorContentExtension}s that are
525      * <i>visible</i> and <i>active</i> for this content service and
526      * have a <b>possibleChildren</b> expression that is <i>enabled</i>
527      * for the given element.
528      */

529     public Set JavaDoc findOverrideableContentExtensionsForPossibleChild(
530             Object JavaDoc anElement) {
531         Set JavaDoc overrideableExtensions = new TreeSet JavaDoc(
532                 ExtensionPriorityComparator.INSTANCE);
533         Set JavaDoc descriptors = findDescriptorsWithPossibleChild(anElement, false);
534         for (Iterator JavaDoc iter = descriptors.iterator(); iter.hasNext();) {
535             INavigatorContentDescriptor descriptor = (INavigatorContentDescriptor) iter
536                     .next();
537             if (descriptor.hasOverridingExtensions()) {
538                 overrideableExtensions.add(getExtension(descriptor));
539             }
540         }
541         return overrideableExtensions;
542     }
543
544     /*
545      * (Non-Javadoc)
546      *
547      * @see INavigatorContentService#getContentDescriptorById(String)
548      */

549     public INavigatorContentDescriptor getContentDescriptorById(
550             String JavaDoc anExtensionId) {
551         return CONTENT_DESCRIPTOR_REGISTRY.getContentDescriptor(anExtensionId);
552     }
553
554     /**
555      *
556      * @param anExtensionId
557      * The id used to define the
558      * <b>org.eclipse.ui.navigator.navigatorContent/navigatorContent</b>
559      * extension.
560      * @return An instance of the content extension for the given extension id.
561      * May return <b>null</b> if the id is invalid.
562      */

563     public INavigatorContentExtension getContentExtensionById(
564             String JavaDoc anExtensionId) {
565         NavigatorContentDescriptor descriptor = CONTENT_DESCRIPTOR_REGISTRY
566                 .getContentDescriptor(anExtensionId);
567         if (descriptor != null)
568             return getExtension(descriptor);
569         return null;
570     }
571
572     /**
573      * Search for extensions that declare the given element in their
574      * <b>triggerPoints</b> expression.
575      *
576      * @param anElement
577      * The element to use in the query
578      * @return The set of {@link INavigatorContentExtension}s that are
579      * <i>visible</i> and <i>active</i> for this content service and
580      * have a <b>triggerPoints</b> expression that is <i>enabled</i>
581      * for the given element.
582      */

583     public Set JavaDoc findContentExtensionsByTriggerPoint(Object JavaDoc anElement) {
584         return findContentExtensionsByTriggerPoint(anElement, true);
585     }
586
587     /**
588      * Search for extensions that declare the given element in their
589      * <b>triggerPoints</b> expression.
590      *
591      * @param anElement
592      * The element to use in the query
593      * @param toLoadIfNecessary
594      * True will force the load of the extension, False will not
595      * @return The set of {@link INavigatorContentExtension}s that are
596      * <i>visible</i> and <i>active</i> for this content service and
597      * have a <b>triggerPoints</b> expression that is <i>enabled</i>
598      * for the given element.
599      */

600     public Set JavaDoc findContentExtensionsByTriggerPoint(Object JavaDoc anElement,
601             boolean toLoadIfNecessary) {
602         Set JavaDoc enabledDescriptors = findDescriptorsByTriggerPoint(anElement);
603         return extractDescriptorInstances(enabledDescriptors, toLoadIfNecessary);
604     }
605
606     /**
607      * Search for extensions that declare the given element in their
608      * <b>possibleChildren</b> expression.
609      *
610      * @param anElement
611      * The element to use in the query
612      * @return The set of {@link INavigatorContentExtension}s that are
613      * <i>visible</i> and <i>active</i> for this content service and
614      * have a <b>possibleChildren</b> expression that is <i>enabled</i>
615      * for the given element.
616      */

617     public Set JavaDoc findContentExtensionsWithPossibleChild(Object JavaDoc anElement) {
618         return findContentExtensionsWithPossibleChild(anElement, true);
619     }
620
621     /**
622      * Search for extensions that declare the given element in their
623      * <b>possibleChildren</b> expression.
624      *
625      * @param anElement
626      * The element to use in the query
627      * @param toLoadIfNecessary
628      * True will force the load of the extension, False will not
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>possibleChildren</b> expression that is <i>enabled</i>
632      * for the given element.
633      */

634     public Set JavaDoc findContentExtensionsWithPossibleChild(Object JavaDoc anElement,
635             boolean toLoadIfNecessary) {
636         Set JavaDoc enabledDescriptors = findDescriptorsWithPossibleChild(anElement);
637         return extractDescriptorInstances(enabledDescriptors, toLoadIfNecessary);
638     }
639
640     /**
641      * Remember that the elements in the given array came from the given source
642      *
643      * @param source
644      * The descriptor of the extension that contributed the set of
645      * elements.
646      * @param elements
647      * An array of elements from the given source.
648      */

649     public synchronized void rememberContribution(
650             NavigatorContentDescriptor source, Object JavaDoc[] elements) {
651
652         if (source != null && elements != null) {
653             for (int i = 0; i < elements.length; i++) {
654                 getContributionMemory().put(elements[i], source);
655             }
656         }
657     }
658
659     /**
660      * Remember that the elements in the given array came from the given source
661      *
662      * @param source
663      * The descriptor of the extension that contributed the set of
664      * elements.
665      * @param element
666      * An element from the given source.
667      */

668     public synchronized void rememberContribution(
669             NavigatorContentDescriptor source, Object JavaDoc element) {
670         if (source != null && element != null) {
671             getContributionMemory().put(element, source);
672         }
673     }
674
675     /**
676      *
677      * @param element
678      * The element contributed by the descriptor to be returned
679      * @return The descriptor that contributed the element or null.
680      * @see #findContentExtensionsWithPossibleChild(Object)
681      */

682     public NavigatorContentDescriptor getSourceOfContribution(Object JavaDoc element) {
683         return (NavigatorContentDescriptor) getContributionMemory()
684                 .get(element);
685     }
686
687     /**
688      * @return Returns the contributionMemory.
689      */

690     public Map JavaDoc getContributionMemory() {
691         if (contributionMemory != null) {
692             return contributionMemory;
693         }
694         synchronized (this) {
695             if (contributionMemory == null) {
696                 contributionMemory = new WeakHashMap JavaDoc();
697             }
698         }
699
700         return contributionMemory;
701     }
702
703     /**
704      * Search for extensions that declare the given element in their
705      * <b>triggerPoints</b> expression.
706      *
707      * @param anElement
708      * The element to use in the query
709      *
710      * @return The set of {@link INavigatorContentDescriptor}s that are
711      * <i>visible</i> and <i>active</i> for this content service and
712      * have a <b>triggerPoints</b> expression that is <i>enabled</i>
713      * for the given element.
714      */

715     public Set JavaDoc findDescriptorsByTriggerPoint(Object JavaDoc anElement) {
716
717         NavigatorContentDescriptor descriptor = getSourceOfContribution(anElement);
718         Set JavaDoc result = new TreeSet JavaDoc(ExtensionPriorityComparator.INSTANCE);
719         if (descriptor != null) {
720             result.add(descriptor);
721         }
722         result.addAll(CONTENT_DESCRIPTOR_REGISTRY
723                 .findDescriptorsForTriggerPoint(anElement, assistant));
724         return result;
725     }
726
727     /**
728      * Search for extensions that declare the given element in their
729      * <b>possibleChildren</b> expression.
730      *
731      * @param anElement
732      * The element to use in the query
733      * @return The set of {@link INavigatorContentDescriptor}s that are
734      * <i>visible</i> and <i>active</i> for this content service and
735      * have a <b>possibleChildren</b> expression that is <i>enabled</i>
736      * for the given element.
737      */

738     public Set JavaDoc findDescriptorsWithPossibleChild(Object JavaDoc anElement) {
739         return findDescriptorsWithPossibleChild(anElement, true);
740     }
741
742     /**
743      * Search for extensions that declare the given element in their
744      * <b>possibleChildren</b> expression.
745      *
746      * @param anElement
747      * The element to use in the query
748      * @param toComputeOverrides
749      * True indicates the overridden tree should be traversed.
750      * @return The set of {@link INavigatorContentDescriptor}s that are
751      * <i>visible</i> and <i>active</i> for this content service and
752      * have a <b>possibleChildren</b> expression that is <i>enabled</i>
753      * for the given element.
754      */

755     public Set JavaDoc findDescriptorsWithPossibleChild(Object JavaDoc anElement,
756             boolean toComputeOverrides) {
757
758         NavigatorContentDescriptor descriptor = getSourceOfContribution(anElement);
759         Set JavaDoc result = new TreeSet JavaDoc(ExtensionPriorityComparator.INSTANCE);
760         if (descriptor != null) {
761             result.add(descriptor);
762         }
763         result.addAll(CONTENT_DESCRIPTOR_REGISTRY
764                 .findDescriptorsForPossibleChild(anElement, assistant,
765                         toComputeOverrides));
766         return result;
767     }
768
769     /*
770      * (non-Javadoc)
771      *
772      * @see org.eclipse.ui.internal.navigator.INavigatorContentService#onExtensionActivation(java.lang.String,
773      * java.lang.String, boolean)
774      */

775     public void onExtensionActivation(String JavaDoc aViewerId,
776             String JavaDoc[] aNavigatorExtensionId, boolean toEnable) {
777         synchronized (this) {
778             try {
779                 NavigatorContentDescriptor key;
780                 NavigatorContentExtension extension;
781                 for (Iterator JavaDoc iter = contentExtensions.keySet().iterator(); iter
782                         .hasNext();) {
783                     key = (NavigatorContentDescriptor) iter.next();
784                     INavigatorActivationService activation = getActivationService();
785                     if (!activation.isNavigatorExtensionActive(key.getId())) {
786                         extension = (NavigatorContentExtension) contentExtensions
787                                 .get(key);
788                         iter.remove();
789                         /*
790                          * There really shouldn't be any way that this can be
791                          * null, but just to be safe
792                          */

793                         if (extension != null) {
794                             extension.dispose();
795                         }
796                     }
797                 }
798             } catch (RuntimeException JavaDoc e) {
799                 String JavaDoc msg = e.getMessage() != null ? e.getMessage() : e
800                         .toString();
801                 NavigatorPlugin.logError(0, msg, e);
802             }
803         }
804         update();
805     }
806
807     /*
808      * (non-Javadoc)
809      *
810      * @see org.eclipse.ui.internal.navigator.INavigatorContentService#update()
811      */

812     public void update() {
813         rootContentProviders = null;
814         if (structuredViewerManager != null) {
815             structuredViewerManager.safeRefresh();
816         }
817     }
818
819     /*
820      * (non-Javadoc)
821      *
822      * @see org.eclipse.ui.internal.navigator.INavigatorContentService#getViewerId()
823      */

824     public final String JavaDoc getViewerId() {
825         return viewerDescriptor.getViewerId();
826     }
827
828     /**
829      *
830      * @param aDescriptorKey
831      * A descriptor
832      * @return The cached NavigatorContentExtension from the descriptor
833      */

834     public final NavigatorContentExtension getExtension(
835             INavigatorContentDescriptor aDescriptorKey) {
836         return getExtension(aDescriptorKey, true);
837     }
838
839     /**
840      *
841      * @param aDescriptorKey
842      * @param toLoadIfNecessary
843      * True if the extension should be loaded if it is not already.
844      * @return The instance of the extension for the given descriptor key.
845      */

846     public final NavigatorContentExtension getExtension(
847             INavigatorContentDescriptor aDescriptorKey,
848             boolean toLoadIfNecessary) {
849         /* Query and return the relevant descriptor instance */
850         NavigatorContentExtension extension = (NavigatorContentExtension) contentExtensions
851                 .get(aDescriptorKey);
852         if (extension != null || !toLoadIfNecessary) {
853             return extension;
854         }
855
856         /*
857          * If the descriptor instance hasn't been created yet, then we need to
858          * (1) verify that it wasn't added by another thread, (2) create and add
859          * the result into the map
860          */

861         synchronized (this) {
862             extension = (NavigatorContentExtension) contentExtensions
863                     .get(aDescriptorKey);
864             if (extension == null) {
865                 contentExtensions.put(aDescriptorKey,
866                         (extension = new NavigatorContentExtension(
867                                 (NavigatorContentDescriptor) aDescriptorKey,
868                                 this, structuredViewerManager)));
869                 notifyListeners(extension);
870             }
871         }
872         return extension;
873
874     }
875
876     /*
877      * (non-Javadoc)
878      *
879      * @see org.eclipse.ui.internal.navigator.INavigatorContentService#getViewerDescriptor()
880      */

881     public INavigatorViewerDescriptor getViewerDescriptor() {
882         return viewerDescriptor;
883     }
884
885     /*
886      * (non-Javadoc)
887      *
888      * @see org.eclipse.ui.internal.navigator.INavigatorContentService#restoreState(org.eclipse.ui.IMemento)
889      */

890     public void restoreState(final IMemento aMemento) {
891         synchronized (this) {
892             List JavaDoc runnables = new ArrayList JavaDoc();
893             for (Iterator JavaDoc extensionItr = getExtensions().iterator(); extensionItr
894                     .hasNext();) {
895                 final NavigatorContentExtension element = (NavigatorContentExtension) extensionItr
896                         .next();
897                 ISafeRunnable runnable = new ISafeRunnable() {
898                     public void run() throws Exception JavaDoc {
899                         element.restoreState(aMemento);
900                     }
901
902                     public void handleException(Throwable JavaDoc exception) {
903                         NavigatorPlugin.logError(0,
904                                 "Could not restore state for Common Navigator content extension" //$NON-NLS-1$
905
+ element.getId(), exception);
906                     }
907                 };
908                 runnables.add(runnable);
909             }
910             for (Iterator JavaDoc iterator = runnables.iterator(); iterator.hasNext();) {
911                 ISafeRunnable runnable = (ISafeRunnable) iterator.next();
912                 SafeRunner.run(runnable);
913             }
914         }
915     }
916
917     /*
918      * (non-Javadoc)
919      *
920      * @see org.eclipse.ui.internal.navigator.INavigatorContentService#saveState(org.eclipse.ui.IMemento)
921      */

922     public void saveState(final IMemento aMemento) {
923         synchronized (this) {
924             
925             List JavaDoc runnables = new ArrayList JavaDoc();
926             for (Iterator JavaDoc extensionItr = getExtensions().iterator(); extensionItr
927                     .hasNext();) {
928                 final NavigatorContentExtension element = (NavigatorContentExtension) extensionItr
929                         .next();
930                 ISafeRunnable runnable = new ISafeRunnable() {
931                     public void run() throws Exception JavaDoc {
932                         element.saveState(aMemento);
933                     }
934
935                     public void handleException(Throwable JavaDoc exception) {
936                         NavigatorPlugin.logError(0,
937                                 "Could not save state for Common Navigator content extension" //$NON-NLS-1$
938
+ element.getId(), exception);
939                     }
940                 };
941                 runnables.add(runnable);
942             }
943             for (Iterator JavaDoc iterator = runnables.iterator(); iterator.hasNext();) {
944                 ISafeRunnable runnable = (ISafeRunnable) iterator.next();
945                 SafeRunner.run(runnable);
946             }
947         }
948     }
949
950     public boolean isActive(String JavaDoc anExtensionId) {
951         return assistant.isActive(anExtensionId);
952     }
953
954     public boolean isVisible(String JavaDoc anExtensionId) {
955         return assistant.isVisible(anExtensionId);
956     }
957
958     protected final Collection JavaDoc getExtensions() {
959         return (contentExtensions.size() > 0) ? Collections
960                 .unmodifiableCollection(contentExtensions.values())
961                 : Collections.EMPTY_LIST;
962     }
963
964     /*
965      * (non-Javadoc)
966      *
967      * @see org.eclipse.ui.internal.navigator.INavigatorContentService#addListener(org.eclipse.ui.internal.navigator.extensions.INavigatorContentServiceListener)
968      */

969     public void addListener(INavigatorContentServiceListener aListener) {
970         listeners.add(aListener);
971     }
972
973     /*
974      * (non-Javadoc)
975      *
976      * @see org.eclipse.ui.navigator.INavigatorContentService#getFilterService()
977      */

978     public INavigatorFilterService getFilterService() {
979         if (navigatorFilterService == null) {
980             navigatorFilterService = new NavigatorFilterService(this);
981         }
982         return navigatorFilterService;
983     }
984
985     /*
986      * (non-Javadoc)
987      *
988      * @see org.eclipse.ui.navigator.INavigatorContentService#getFilterService()
989      */

990     public INavigatorSorterService getSorterService() {
991         if (navigatorSorterService == null) {
992             navigatorSorterService = new NavigatorSorterService(this);
993         }
994         return navigatorSorterService;
995     }
996
997     /*
998      * (non-Javadoc)
999      *
1000     * @see org.eclipse.ui.navigator.INavigatorContentService#getFilterService()
1001     */

1002    public INavigatorPipelineService getPipelineService() {
1003        if (navigatorPipelineService == null) {
1004            navigatorPipelineService = new NavigatorPipelineService(this);
1005        }
1006        return navigatorPipelineService;
1007    }
1008
1009    /*
1010     * (non-Javadoc)
1011     *
1012     * @see org.eclipse.ui.navigator.INavigatorContentService#getDnDService()
1013     */

1014    public INavigatorDnDService getDnDService() {
1015        if (navigatorDnDService == null) {
1016            navigatorDnDService = new NavigatorDnDService(this);
1017        }
1018        return navigatorDnDService;
1019    }
1020
1021    /*
1022     * (non-Javadoc)
1023     *
1024     * @see org.eclipse.ui.navigator.INavigatorContentService#getActivationService()
1025     */

1026    public INavigatorActivationService getActivationService() {
1027
1028        if (navigatorActivationService == null) {
1029            navigatorActivationService = new NavigatorActivationService(this);
1030        }
1031        return navigatorActivationService;
1032    }
1033
1034    /*
1035     * (non-Javadoc)
1036     *
1037     * @see org.eclipse.ui.navigator.INavigatorContentService#getSaveableService()
1038     */

1039    public INavigatorSaveablesService getSaveablesService() {
1040        synchronized (this) {
1041            if (navigatorSaveablesService == null) {
1042                navigatorSaveablesService = new NavigatorSaveablesService(this);
1043                assistant.addListener(navigatorSaveablesService);
1044            }
1045            return navigatorSaveablesService;
1046        }
1047    }
1048
1049    /**
1050     * Not API as of 3.3.
1051     *
1052     * @return The extension state service for this content service.
1053     *
1054     */

1055    public NavigatorExtensionStateService getExtensionStateService() {
1056        if (navigatorExtensionStateService == null) {
1057            navigatorExtensionStateService = new NavigatorExtensionStateService(
1058                    this);
1059        }
1060        return navigatorExtensionStateService;
1061    }
1062
1063    /**
1064     * Non-API method to return a shell.
1065     *
1066     * @return A shell associated with the current viewer (if any) or <b>null</b>.
1067     */

1068    public Shell getShell() {
1069        if (structuredViewerManager != null
1070                && structuredViewerManager.getViewer() != null) {
1071            return structuredViewerManager.getViewer().getControl().getShell();
1072        }
1073        return null;
1074    }
1075
1076    protected boolean isRootExtension(String JavaDoc anExtensionId) {
1077        return assistant.isRootExtension(anExtensionId);
1078    }
1079
1080    /*
1081     * (non-Javadoc)
1082     *
1083     * @see org.eclipse.ui.internal.navigator.INavigatorContentService#removeListener(org.eclipse.ui.internal.navigator.extensions.INavigatorContentServiceListener)
1084     */

1085    public void removeListener(INavigatorContentServiceListener aListener) {
1086        listeners.remove(aListener);
1087    }
1088
1089    /*
1090     * (non-Javadoc)
1091     *
1092     * @see java.lang.Object#toString()
1093     */

1094    public String JavaDoc toString() {
1095        return "ContentService[" + viewerDescriptor.getViewerId() + "]"; //$NON-NLS-1$//$NON-NLS-2$
1096
}
1097
1098    private void notifyListeners(NavigatorContentExtension aDescriptorInstance) {
1099
1100        if (listeners.size() == 0) {
1101            return;
1102        }
1103        INavigatorContentServiceListener listener = null;
1104        List JavaDoc failedListeners = null;
1105        for (Iterator JavaDoc listenersItr = listeners.iterator(); listenersItr
1106                .hasNext();) {
1107            try {
1108                listener = (INavigatorContentServiceListener) listenersItr
1109                        .next();
1110                listener.onLoad(aDescriptorInstance);
1111            } catch (RuntimeException JavaDoc re) {
1112                if (failedListeners == null) {
1113                    failedListeners = new ArrayList JavaDoc();
1114                }
1115                failedListeners.add(listener);
1116            }
1117        }
1118        if (failedListeners != null) {
1119            listeners.removeAll(failedListeners);
1120        }
1121    }
1122
1123    private ITreeContentProvider[] extractContentProviders(
1124            Set JavaDoc theDescriptorInstances) {
1125        if (theDescriptorInstances.size() == 0) {
1126            return NO_CONTENT_PROVIDERS;
1127        }
1128        List JavaDoc resultProvidersList = new ArrayList JavaDoc();
1129        for (Iterator JavaDoc itr = theDescriptorInstances.iterator(); itr.hasNext();) {
1130            resultProvidersList.add(((NavigatorContentExtension) itr.next())
1131                    .internalGetContentProvider());
1132        }
1133        return (ITreeContentProvider[]) resultProvidersList
1134                .toArray(new ITreeContentProvider[resultProvidersList.size()]);
1135    }
1136
1137    private Set JavaDoc extractDescriptorInstances(Set JavaDoc theDescriptors,
1138            boolean toLoadAllIfNecessary) {
1139        if (theDescriptors.size() == 0) {
1140            return Collections.EMPTY_SET;
1141        }
1142        Set JavaDoc resultInstances = new TreeSet JavaDoc(ExtensionPriorityComparator.INSTANCE);
1143        for (Iterator JavaDoc descriptorIter = theDescriptors.iterator(); descriptorIter
1144                .hasNext();) {
1145            NavigatorContentExtension extension = getExtension(
1146                    (NavigatorContentDescriptor) descriptorIter.next(),
1147                    toLoadAllIfNecessary);
1148            if (extension != null) {
1149                resultInstances.add(extension);
1150
1151            }
1152        }
1153        return resultInstances;
1154    }
1155
1156    private ILabelProvider[] extractLabelProviders(Set JavaDoc theDescriptorInstances) {
1157        if (theDescriptorInstances.size() == 0) {
1158            return NO_LABEL_PROVIDERS;
1159        }
1160        List JavaDoc resultProvidersList = new ArrayList JavaDoc();
1161        for (Iterator JavaDoc itr = theDescriptorInstances.iterator(); itr.hasNext();) {
1162            resultProvidersList.add(((NavigatorContentExtension) itr.next())
1163                    .getLabelProvider());
1164        }
1165        return (ILabelProvider[]) resultProvidersList
1166                .toArray(new ILabelProvider[resultProvidersList.size()]);
1167    }
1168
1169}
1170
Popular Tags