KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > navigator > extensions > NavigatorContentDescriptorManager


1 /*******************************************************************************
2  * Copyright (c) 2003, 2006 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.extensions;
12
13 import java.lang.ref.SoftReference JavaDoc;
14 import java.util.Arrays JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.HashSet JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.Map JavaDoc;
19 import java.util.Set JavaDoc;
20 import java.util.TreeSet JavaDoc;
21 import java.util.WeakHashMap JavaDoc;
22
23 import org.eclipse.core.runtime.IConfigurationElement;
24 import org.eclipse.jface.resource.ImageDescriptor;
25 import org.eclipse.jface.resource.ImageRegistry;
26 import org.eclipse.swt.graphics.Image;
27 import org.eclipse.ui.WorkbenchException;
28 import org.eclipse.ui.internal.navigator.NavigatorPlugin;
29 import org.eclipse.ui.internal.navigator.VisibilityAssistant;
30 import org.eclipse.ui.internal.navigator.VisibilityAssistant.VisibilityListener;
31 import org.eclipse.ui.navigator.INavigatorContentDescriptor;
32 import org.eclipse.ui.plugin.AbstractUIPlugin;
33
34 /**
35  * <p>
36  * <strong>EXPERIMENTAL</strong>. This class or interface has been added as
37  * part of a work in progress. There is a guarantee neither that this API will
38  * work nor that it will remain the same. Please do not use this API without
39  * consulting with the Platform/UI team.
40  * </p>
41  *
42  * @since 3.2
43  */

44 public class NavigatorContentDescriptorManager {
45
46     private static final NavigatorContentDescriptorManager INSTANCE = new NavigatorContentDescriptorManager();
47  
48     private final Map JavaDoc firstClassDescriptorsMap = new HashMap JavaDoc();
49
50     private final Map JavaDoc allDescriptors = new HashMap JavaDoc();
51
52     private class EvaluationCache implements VisibilityListener {
53
54         private final Map JavaDoc evaluations/*<Object, NavigatorContentDescriptor[]>*/ = new HashMap JavaDoc();
55         private final Map JavaDoc evaluationsWithOverrides/*<Object, NavigatorContentDescriptor[]>*/ = new HashMap JavaDoc();
56
57         EvaluationCache(VisibilityAssistant anAssistant) {
58             anAssistant.addListener(this);
59         }
60
61         protected final NavigatorContentDescriptor[] getDescriptors(Object JavaDoc anElement) {
62             return getDescriptors(anElement, true);
63         }
64
65         protected final void setDescriptors(Object JavaDoc anElement, NavigatorContentDescriptor[] theDescriptors) {
66             setDescriptors(anElement, theDescriptors, true);
67         }
68         
69         protected final NavigatorContentDescriptor[] getDescriptors(Object JavaDoc anElement, boolean toComputeOverrides) {
70             
71             if(anElement == null)
72                 return null;
73             
74             NavigatorContentDescriptor[] cachedDescriptors = null;
75             if(toComputeOverrides) {
76                 SoftReference JavaDoc cache = (SoftReference JavaDoc) evaluations.get(anElement);
77                 if( cache != null && (cachedDescriptors = (NavigatorContentDescriptor[]) cache.get()) == null)
78                     evaluations.remove(anElement);
79                 return cachedDescriptors;
80             }
81             SoftReference JavaDoc cache = (SoftReference JavaDoc) evaluationsWithOverrides.get(anElement);
82             if( cache != null && (cachedDescriptors = (NavigatorContentDescriptor[]) cache.get()) == null)
83                 evaluationsWithOverrides.remove(anElement);
84             return cachedDescriptors;
85              
86         }
87
88         protected final void setDescriptors(Object JavaDoc anElement, NavigatorContentDescriptor[] theDescriptors, boolean toComputeOverrides) {
89             if(anElement != null) {
90                 if(toComputeOverrides)
91                     evaluations.put(new EvalutationReference(anElement), new SoftReference JavaDoc(theDescriptors));
92                 else
93                     evaluationsWithOverrides.put(new EvalutationReference(anElement), new SoftReference JavaDoc(theDescriptors));
94             }
95         }
96       
97         /*
98          * (non-Javadoc)
99          *
100          * @see org.eclipse.ui.internal.navigator.VisibilityAssistant.VisibilityListener#onVisibilityOrActivationChange()
101          */

102         public void onVisibilityOrActivationChange() {
103             evaluations.clear();
104             evaluationsWithOverrides.clear();
105         }
106     }
107
108     /* Map of (VisibilityAssistant, EvaluationCache)-pairs */
109     private final Map JavaDoc cachedTriggerPointEvaluations = new WeakHashMap JavaDoc();
110
111     /* Map of (VisibilityAssistant, EvaluationCache)-pairs */
112     private final Map JavaDoc cachedPossibleChildrenEvaluations = new WeakHashMap JavaDoc();
113
114     private ImageRegistry imageRegistry;
115
116     private final Set JavaDoc overridingDescriptors = new HashSet JavaDoc();
117
118     private final Set JavaDoc saveablesProviderDescriptors = new HashSet JavaDoc();
119     
120     private final Set JavaDoc firstClassDescriptorsSet = new HashSet JavaDoc();
121
122     /**
123      * @return the singleton instance of the manager
124      */

125     public static NavigatorContentDescriptorManager getInstance() {
126         return INSTANCE;
127     }
128
129     private NavigatorContentDescriptorManager() {
130         new NavigatorContentDescriptorRegistry().readRegistry();
131     }
132
133     /**
134      *
135      * @return Returns all content descriptor(s).
136      */

137     public NavigatorContentDescriptor[] getAllContentDescriptors() {
138         NavigatorContentDescriptor[] finalDescriptors = new NavigatorContentDescriptor[allDescriptors
139                 .size()];
140         finalDescriptors = (NavigatorContentDescriptor[]) allDescriptors.values().toArray(finalDescriptors);
141         Arrays.sort(finalDescriptors, ExtensionPriorityComparator.INSTANCE);
142         return finalDescriptors;
143     }
144
145     /**
146      *
147      * @return Returns all content descriptors that provide saveables.
148      */

149     public NavigatorContentDescriptor[] getContentDescriptorsWithSaveables() {
150         NavigatorContentDescriptor[] finalDescriptors = new NavigatorContentDescriptor[saveablesProviderDescriptors
151                                                                                        .size()];
152         saveablesProviderDescriptors.toArray(finalDescriptors);
153         Arrays.sort(finalDescriptors, ExtensionPriorityComparator.INSTANCE);
154         return finalDescriptors;
155     }
156     
157     /**
158      *
159      * Returns all content descriptor(s) which enable for the given element.
160      *
161      * @param anElement
162      * the element to return the best content descriptor for
163      *
164      * @param aVisibilityAssistant
165      * The relevant viewer assistant; used to filter out unbound
166      * content descriptors.
167      * @return the best content descriptor for the given element.
168      */

169     public Set JavaDoc findDescriptorsForTriggerPoint(Object JavaDoc anElement,
170             VisibilityAssistant aVisibilityAssistant) {
171         EvaluationCache cache = getEvaluationCache(
172                 cachedTriggerPointEvaluations, aVisibilityAssistant);
173
174         Set JavaDoc descriptors = new TreeSet JavaDoc(ExtensionPriorityComparator.INSTANCE);
175         NavigatorContentDescriptor[] cachedDescriptors = null;
176         if ( (cachedDescriptors = cache.getDescriptors(anElement)) != null) {
177             descriptors.addAll(Arrays.asList(cachedDescriptors));
178         }
179
180         /* Find other ContentProviders which enable for this object */
181         for (Iterator JavaDoc contentDescriptorsItr = firstClassDescriptorsMap.values()
182                 .iterator(); contentDescriptorsItr.hasNext();) {
183             NavigatorContentDescriptor descriptor = (NavigatorContentDescriptor) contentDescriptorsItr
184                     .next();
185
186             if (aVisibilityAssistant.isActive(descriptor)
187                     && aVisibilityAssistant.isVisible(descriptor)
188                     && descriptor.isTriggerPoint(anElement)) {
189                 descriptors.add(descriptor);
190             }
191         }
192
193         cache.setDescriptors(anElement, (NavigatorContentDescriptor[]) descriptors.toArray(new NavigatorContentDescriptor[descriptors.size()]));
194
195         return descriptors;
196     }
197
198     private EvaluationCache getEvaluationCache(Map JavaDoc anEvaluationMap,
199             VisibilityAssistant aVisibilityAssistant) {
200         EvaluationCache c = (EvaluationCache) anEvaluationMap
201                 .get(aVisibilityAssistant);
202         if (c == null) {
203             anEvaluationMap.put(aVisibilityAssistant, c = new EvaluationCache(
204                     aVisibilityAssistant));
205         }
206         return c;
207
208     }
209     
210     /**
211      *
212      * Returns all content descriptor(s) which enable for the given element.
213      *
214      * @param anElement
215      * the element to return the best content descriptor for
216      *
217      * @param aVisibilityAssistant
218      * The relevant viewer assistant; used to filter out unbound
219      * content descriptors.
220      * @return the best content descriptor for the given element.
221      */

222     public Set JavaDoc findDescriptorsForPossibleChild(Object JavaDoc anElement,
223             VisibilityAssistant aVisibilityAssistant) {
224         return findDescriptorsForPossibleChild(anElement, aVisibilityAssistant, true);
225     }
226
227     /**
228      *
229      * Returns all content descriptor(s) which enable for the given element.
230      *
231      * @param anElement
232      * the element to return the best content descriptor for
233      *
234      * @param aVisibilityAssistant
235      * The relevant viewer assistant; used to filter out unbound
236      * content descriptors.
237      * @return the best content descriptor for the given element.
238      */

239     public Set JavaDoc findDescriptorsForPossibleChild(Object JavaDoc anElement,
240             VisibilityAssistant aVisibilityAssistant, boolean toComputeOverrides) {
241
242         EvaluationCache cache = getEvaluationCache(
243                 cachedPossibleChildrenEvaluations, aVisibilityAssistant);
244         
245         Set JavaDoc descriptors = new TreeSet JavaDoc(ExtensionPriorityComparator.INSTANCE);
246         NavigatorContentDescriptor[] cachedDescriptors = null;
247         if ( (cachedDescriptors = cache.getDescriptors(anElement, toComputeOverrides)) != null) {
248             descriptors.addAll(Arrays.asList(cachedDescriptors));
249         }
250         
251         if(toComputeOverrides) {
252             addDescriptorsForPossibleChild(anElement, firstClassDescriptorsSet,
253                 aVisibilityAssistant, descriptors);
254         } else {
255
256             NavigatorContentDescriptor descriptor;
257             /* Find other ContentProviders which enable for this object */
258             for (Iterator JavaDoc contentDescriptorsItr = allDescriptors.values().iterator(); contentDescriptorsItr
259                     .hasNext();) {
260                 descriptor = (NavigatorContentDescriptor) contentDescriptorsItr
261                         .next();
262
263                 boolean isApplicable = aVisibilityAssistant.isActive(descriptor)
264                         && aVisibilityAssistant.isVisible(descriptor)
265                         && descriptor.isPossibleChild(anElement);
266
267                  if (isApplicable) {
268                     descriptors.add(descriptor);
269                 }
270
271             }
272         }
273         cache.setDescriptors(anElement, (NavigatorContentDescriptor[]) descriptors.toArray(new NavigatorContentDescriptor[descriptors.size()]), toComputeOverrides);
274
275         return descriptors;
276     }
277
278     private boolean addDescriptorsForPossibleChild(Object JavaDoc anElement,
279             Set JavaDoc theChildDescriptors, VisibilityAssistant aVisibilityAssistant,
280             Set JavaDoc theFoundDescriptors) {
281         int initialSize = theFoundDescriptors.size();
282
283         NavigatorContentDescriptor descriptor;
284         /* Find other ContentProviders which enable for this object */
285         for (Iterator JavaDoc contentDescriptorsItr = theChildDescriptors.iterator(); contentDescriptorsItr
286                 .hasNext();) {
287             descriptor = (NavigatorContentDescriptor) contentDescriptorsItr
288                     .next();
289
290             boolean isApplicable = aVisibilityAssistant.isActive(descriptor)
291                     && aVisibilityAssistant.isVisible(descriptor)
292                     && descriptor.isPossibleChild(anElement);
293
294             if (descriptor.hasOverridingExtensions()) {
295
296                 boolean isOverridden = addDescriptorsForPossibleChild(
297                         anElement, descriptor.getOverriddingExtensions(),
298                         aVisibilityAssistant, theFoundDescriptors);
299
300                 if (!isOverridden && isApplicable) {
301                     theFoundDescriptors.add(descriptor);
302                 }
303
304             } else if (isApplicable) {
305                 theFoundDescriptors.add(descriptor);
306             }
307
308         }
309         return initialSize < theFoundDescriptors.size();
310
311     }
312
313     /**
314      * Returns the navigator content descriptor with the given id.
315      *
316      * @param id
317      * The id of the content descriptor that should be returned
318      * @return The content descriptor of the given id
319      */

320     public NavigatorContentDescriptor getContentDescriptor(String JavaDoc id) {
321         return (NavigatorContentDescriptor) allDescriptors.get(id);
322     }
323
324     /**
325      *
326      * @param descriptorId
327      * The unique id of a particular descriptor
328      * @return The name (value of the 'name' attribute) of the given descriptor
329      */

330     public String JavaDoc getText(String JavaDoc descriptorId) {
331         INavigatorContentDescriptor descriptor = getContentDescriptor(descriptorId);
332         if (descriptor != null) {
333             return descriptor.getName();
334         }
335         return descriptorId;
336     }
337
338     /**
339      *
340      * @param descriptorId
341      * The unique id of a particular descriptor
342      * @return The image (corresponding to the value of the 'icon' attribute) of
343      * the given descriptor
344      */

345     public Image getImage(String JavaDoc descriptorId) {
346         return retrieveAndStoreImage(descriptorId);
347     }
348
349     protected Image retrieveAndStoreImage(String JavaDoc descriptorId) {
350         NavigatorContentDescriptor contentDescriptor = getContentDescriptor(descriptorId);
351
352         Image image = null;
353         if (contentDescriptor != null) {
354             String JavaDoc icon = contentDescriptor.getIcon();
355             if (icon != null) {
356                 image = getImageRegistry().get(icon);
357                 if (image == null || image.isDisposed()) {
358                     ImageDescriptor imageDescriptor = AbstractUIPlugin
359                             .imageDescriptorFromPlugin(contentDescriptor
360                                     .getContribution().getPluginId(), icon);
361                     if (imageDescriptor != null) {
362                         image = imageDescriptor.createImage();
363                         if (image != null) {
364                             getImageRegistry().put(icon, image);
365                         }
366                     }
367                 }
368             }
369         }
370         return image;
371     }
372
373     /**
374      * @param desc
375      */

376     private void addNavigatorContentDescriptor(NavigatorContentDescriptor desc) {
377         if (desc == null) {
378             return;
379         }
380         synchronized (firstClassDescriptorsMap) {
381             if (firstClassDescriptorsMap.containsKey(desc.getId())) {
382                 NavigatorPlugin
383                         .logError(
384                                 0,
385                                 "An extension already exists with id \"" + desc.getId() + "\".", null); //$NON-NLS-1$ //$NON-NLS-2$
386
} else {
387                 if (desc.getSuppressedExtensionId() == null) {
388                     firstClassDescriptorsMap.put(desc.getId(), desc);
389                     firstClassDescriptorsSet.add(desc);
390                 } else {
391                     overridingDescriptors.add(desc);
392                 }
393                 allDescriptors.put(desc.getId(), desc);
394                 if (desc.hasSaveablesProvider()) {
395                     saveablesProviderDescriptors.add(desc);
396                 }
397             }
398         }
399     }
400
401     /**
402      *
403      */

404     private void computeOverrides() {
405         if (overridingDescriptors.size() > 0) {
406             NavigatorContentDescriptor descriptor;
407             NavigatorContentDescriptor overriddenDescriptor;
408             for (Iterator JavaDoc overridingIterator = overridingDescriptors.iterator(); overridingIterator
409                     .hasNext();) {
410                 descriptor = (NavigatorContentDescriptor) overridingIterator
411                         .next();
412                 overriddenDescriptor = (NavigatorContentDescriptor) allDescriptors
413                         .get(descriptor.getSuppressedExtensionId());
414                 if (overriddenDescriptor != null) {
415
416                     /*
417                      * add the descriptor as an overriding extension for its
418                      * suppressed extension
419                      */

420                     overriddenDescriptor.getOverriddingExtensions().add(
421                             descriptor);
422                     descriptor.setOverriddenDescriptor(overriddenDescriptor);
423                     /*
424                      * the always policy implies this is also a top-level
425                      * extension
426                      */

427                     if (descriptor.getOverridePolicy() == OverridePolicy.InvokeAlwaysRegardlessOfSuppressedExt) {
428                         firstClassDescriptorsMap.put(descriptor.getId(),
429                                 descriptor);
430                         firstClassDescriptorsSet.add(descriptor);
431                     }
432
433                 } else {
434                     NavigatorPlugin.logError(0,
435                             "Invalid suppressedExtensionId (\"" //$NON-NLS-1$
436
+ descriptor.getSuppressedExtensionId()
437                                     + "\" specified from " //$NON-NLS-1$
438
+ descriptor.getContribution()
439                                             .getPluginId()
440                                     + ". No extension with matching id found.", //$NON-NLS-1$
441
null);
442                 }
443             }
444         }
445     }
446  
447     private ImageRegistry getImageRegistry() {
448         if (imageRegistry == null) {
449             imageRegistry = new ImageRegistry();
450         }
451         return imageRegistry;
452     }
453
454     private class NavigatorContentDescriptorRegistry extends
455             NavigatorContentRegistryReader {
456
457         /*
458          * (non-Javadoc)
459          *
460          * @see org.eclipse.ui.internal.navigator.extensions.RegistryReader#readRegistry()
461          */

462         public void readRegistry() {
463             super.readRegistry();
464             computeOverrides();
465         }
466
467         protected boolean readElement(IConfigurationElement anElement) {
468             if (TAG_NAVIGATOR_CONTENT.equals(anElement.getName())) {
469                 try {
470                     addNavigatorContentDescriptor(new NavigatorContentDescriptor(
471                             anElement));
472
473                 } catch (WorkbenchException e) {
474                     // log an error since its not safe to open a dialog here
475
NavigatorPlugin.log(e.getStatus());
476                 }
477             }
478             return super.readElement(anElement);
479         }
480     }
481
482 }
483
Popular Tags