KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > menus > MenuAdditionCacheEntry


1 /*******************************************************************************
2  * Copyright (c) 2006, 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
12 package org.eclipse.ui.internal.menus;
13
14 import java.util.HashMap JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.Map JavaDoc;
17 import java.util.Set JavaDoc;
18
19 import org.eclipse.core.expressions.Expression;
20 import org.eclipse.core.expressions.ExpressionConverter;
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.core.runtime.IConfigurationElement;
23 import org.eclipse.core.runtime.InvalidRegistryObjectException;
24 import org.eclipse.jface.action.GroupMarker;
25 import org.eclipse.jface.action.IContributionItem;
26 import org.eclipse.jface.action.MenuManager;
27 import org.eclipse.jface.action.Separator;
28 import org.eclipse.jface.action.ToolBarContributionItem;
29 import org.eclipse.jface.action.ToolBarManager;
30 import org.eclipse.jface.resource.ImageDescriptor;
31 import org.eclipse.ui.IWorkbenchWindow;
32 import org.eclipse.ui.actions.CompoundContributionItem;
33 import org.eclipse.ui.internal.WorkbenchWindow;
34 import org.eclipse.ui.internal.provisional.presentations.IActionBarPresentationFactory;
35 import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
36 import org.eclipse.ui.internal.util.Util;
37 import org.eclipse.ui.menus.AbstractContributionFactory;
38 import org.eclipse.ui.menus.CommandContributionItem;
39 import org.eclipse.ui.menus.IContributionRoot;
40 import org.eclipse.ui.menus.IMenuService;
41 import org.eclipse.ui.menus.WorkbenchWindowControlContribution;
42 import org.eclipse.ui.plugin.AbstractUIPlugin;
43 import org.eclipse.ui.services.IServiceLocator;
44
45 /**
46  * @since 3.3
47  *
48  */

49 public class MenuAdditionCacheEntry extends AbstractContributionFactory {
50     private IConfigurationElement additionElement;
51
52     // Caches
53

54     /**
55      * Maps an IContributionItem to its corresponding IConfigurationElement
56      */

57     Map JavaDoc iciToConfigElementMap = new HashMap JavaDoc();
58
59     /**
60      * If an {@link IConfigurationElement} is in the Set then we have already
61      * tried (and failed) to load the associated ExecutableExtension.
62      *
63      * This is used to prevent multiple retries which would spam the Log.
64      */

65     Set JavaDoc failedLoads = new HashSet JavaDoc();
66
67     /**
68      * Maps an IConfigurationElement to its parsed Expression
69      */

70     private HashMap JavaDoc visWhenMap = new HashMap JavaDoc();
71
72     /**
73      * The menu service on which to generate all subcaches.
74      */

75     private IMenuService menuService;
76
77     public MenuAdditionCacheEntry(IMenuService menuService,
78             IConfigurationElement element, String JavaDoc location, String JavaDoc namespace) {
79         super(location, namespace);
80         this.menuService = menuService;
81         this.additionElement = element;
82         generateSubCaches();
83     }
84
85     /**
86      *
87      */

88     private void generateSubCaches() {
89         IConfigurationElement[] items = additionElement.getChildren();
90         for (int i = 0; i < items.length; i++) {
91             String JavaDoc itemType = items[i].getName();
92             if (IWorkbenchRegistryConstants.TAG_MENU.equals(itemType)
93                     || IWorkbenchRegistryConstants.TAG_TOOLBAR.equals(itemType)) {
94                 // Menus and toolbars are special...we have to add any sub menu
95
// items into their own cache
96
// If the locationURI is null then this should be a sub menu
97
// addition..create the 'root' URI
98

99                 String JavaDoc location = new MenuLocationURI(getLocation())
100                         .getScheme()
101                         + ":" + MenuAdditionCacheEntry.getId(items[i]); //$NON-NLS-1$
102

103                 // -ALL- contibuted menus must have an id so create one
104
// if necessary
105
MenuAdditionCacheEntry subMenuEntry = new MenuAdditionCacheEntry(
106                         menuService, items[i], location, getNamespace());
107                 menuService.addContributionFactory(subMenuEntry);
108             }
109         }
110     }
111
112     private Expression getVisibleWhenForItem(IContributionItem item) {
113         IConfigurationElement configElement = (IConfigurationElement) iciToConfigElementMap
114                 .get(item);
115         if (configElement == null)
116             return null;
117
118         if (!visWhenMap.containsKey(configElement)) {
119             // Not parsed yet
120
try {
121                 IConfigurationElement[] visibleConfig = configElement
122                         .getChildren(IWorkbenchRegistryConstants.TAG_VISIBLE_WHEN);
123                 if (visibleConfig.length > 0 && visibleConfig.length < 2) {
124                     IConfigurationElement[] visibleChild = visibleConfig[0]
125                             .getChildren();
126                     if (visibleChild.length > 0) {
127                         Expression visWhen = ExpressionConverter.getDefault()
128                                 .perform(visibleChild[0]);
129                         visWhenMap.put(configElement, visWhen);
130                     }
131                 }
132             } catch (InvalidRegistryObjectException e) {
133                 visWhenMap.put(configElement, null);
134                 // TODO Auto-generated catch block
135
e.printStackTrace();
136             } catch (CoreException e) {
137                 visWhenMap.put(configElement, null);
138                 // TODO Auto-generated catch block
139
e.printStackTrace();
140             }
141         }
142
143         return (Expression) visWhenMap.get(configElement);
144     }
145
146     /*
147      * (non-Javadoc)
148      *
149      * @see org.eclipse.ui.internal.menus.AbstractContributionFactory#createContributionItems(org.eclipse.ui.internal.menus.IMenuService,
150      * java.util.List)
151      */

152     public void createContributionItems(IServiceLocator serviceLocator,
153             IContributionRoot additions) {
154         IActionBarPresentationFactory actionBarPresentationFactory = null;
155
156         WorkbenchWindow window = (WorkbenchWindow) serviceLocator
157                 .getService(IWorkbenchWindow.class);
158         if (window != null) {
159             actionBarPresentationFactory = window
160                     .getActionBarPresentationFactory();
161         }
162
163         IConfigurationElement[] items = additionElement.getChildren();
164         for (int i = 0; i < items.length; i++) {
165             String JavaDoc itemType = items[i].getName();
166             IContributionItem newItem = null;
167
168             if (IWorkbenchRegistryConstants.TAG_COMMAND.equals(itemType)) {
169                 newItem = createCommandAdditionContribution(serviceLocator,
170                         items[i]);
171             } else if (IWorkbenchRegistryConstants.TAG_DYNAMIC.equals(itemType)) {
172                 newItem = createDynamicAdditionContribution(items[i]);
173             } else if (IWorkbenchRegistryConstants.TAG_CONTROL.equals(itemType)) {
174                 newItem = createControlAdditionContribution(items[i]);
175             } else if (IWorkbenchRegistryConstants.TAG_SEPARATOR
176                     .equals(itemType)) {
177                 newItem = createSeparatorAdditionContribution(items[i]);
178             } else if (IWorkbenchRegistryConstants.TAG_MENU.equals(itemType)) {
179                 newItem = createMenuAdditionContribution(items[i]);
180             } else if (IWorkbenchRegistryConstants.TAG_TOOLBAR.equals(itemType)) {
181                 newItem = createToolBarAdditionContribution(
182                         actionBarPresentationFactory, items[i]);
183             }
184
185             // Cache the relationship between the ICI and the
186
// registry element used to back it
187
if (newItem != null) {
188                 iciToConfigElementMap.put(newItem, items[i]);
189                 additions.addContributionItem(newItem,
190                         getVisibleWhenForItem(newItem));
191             }
192         }
193     }
194
195     /**
196      * @param configurationElement
197      * @return
198      */

199     private IContributionItem createToolBarAdditionContribution(
200             IActionBarPresentationFactory actionBarPresentationFactory,
201             IConfigurationElement configurationElement) {
202         if (!getLocation().startsWith("toolbar")) { //$NON-NLS-1$
203
return null;
204         }
205         if (actionBarPresentationFactory != null) {
206             return actionBarPresentationFactory.createToolBarContributionItem(
207                     actionBarPresentationFactory.createToolBarManager(),
208                     getId(configurationElement));
209         }
210         return new ToolBarContributionItem(new ToolBarManager(),
211                 getId(configurationElement));
212     }
213
214     /**
215      * @param configurationElement
216      * @return the menu manager
217      */

218     private IContributionItem createMenuAdditionContribution(
219             final IConfigurationElement menuAddition) {
220         // Is this for a menu or a ToolBar ? We can't create
221
// a menu directly under a Toolbar; we have to add an
222
// item of style 'pulldown'
223
if (getLocation().startsWith("toolbar")) { //$NON-NLS-1$
224
return null;
225         }
226
227         String JavaDoc text = getLabel(menuAddition);
228         String JavaDoc mnemonic = getMnemonic(menuAddition);
229         if (text != null && mnemonic != null) {
230             int idx = text.indexOf(mnemonic);
231             if (idx != -1) {
232                 text = text.substring(0, idx) + '&' + text.substring(idx);
233             }
234         }
235         return new MenuManager(text, getId(menuAddition));
236     }
237
238     /**
239      * @param configurationElement
240      * @return
241      */

242     private IContributionItem createSeparatorAdditionContribution(
243             final IConfigurationElement sepAddition) {
244         if (isSeparatorVisible(sepAddition)) {
245             return new Separator(getName(sepAddition));
246         }
247         return new GroupMarker(getName(sepAddition));
248     }
249
250     /**
251      * @return
252      */

253     private IContributionItem createDynamicAdditionContribution(
254             final IConfigurationElement dynamicAddition) {
255         // If we've already tried (and failed) to load the
256
// executable extension then skip this addition.
257
if (failedLoads.contains(dynamicAddition))
258             return null;
259
260         // Attempt to load the addition's EE (creates a new instance)
261
final CompoundContributionItem loadedDynamicContribution = (CompoundContributionItem) Util
262                 .safeLoadExecutableExtension(dynamicAddition,
263                         IWorkbenchRegistryConstants.ATT_CLASS,
264                         CompoundContributionItem.class);
265
266         // Cache failures
267
if (loadedDynamicContribution == null) {
268             failedLoads.add(loadedDynamicContribution);
269             return null;
270         }
271
272         // TODO provide a proxy IContributionItem that defers instantiation
273
// adding contribution items in a menu instantiates this object ...
274
// we need to defer loading until fill(*) is called.
275
return loadedDynamicContribution;
276     }
277
278     /**
279      * @return
280      */

281     private IContributionItem createControlAdditionContribution(
282             final IConfigurationElement widgetAddition) {
283         if (!getLocation().startsWith("toolbar")) { //$NON-NLS-1$
284
return null;
285         }
286         // If we've already tried (and failed) to load the
287
// executable extension then skip this addirion.
288
if (failedLoads.contains(widgetAddition))
289             return null;
290
291         // Attempt to load the addition's EE (creates a new instance)
292
final WorkbenchWindowControlContribution loadedWidget = (WorkbenchWindowControlContribution) Util
293                 .safeLoadExecutableExtension(widgetAddition,
294                         IWorkbenchRegistryConstants.ATT_CLASS,
295                         WorkbenchWindowControlContribution.class);
296
297         // Cache failures
298
if (loadedWidget == null) {
299             failedLoads.add(widgetAddition);
300             return null;
301         }
302
303         // explicitly set the id
304
((InternalControlContribution) loadedWidget)
305                 .setId(getId(widgetAddition));
306
307         return loadedWidget;
308     }
309
310     /**
311      * @param configurationElement
312      * @return
313      */

314     private IContributionItem createCommandAdditionContribution(
315             IServiceLocator locator, final IConfigurationElement commandAddition) {
316         return new CommandContributionItem(locator, getId(commandAddition),
317                 getCommandId(commandAddition), getParameters(commandAddition),
318                 getIconDescriptor(commandAddition),
319                 getDisabledIconDescriptor(commandAddition),
320                 getHoverIconDescriptor(commandAddition),
321                 getLabel(commandAddition), getMnemonic(commandAddition),
322                 getTooltip(commandAddition), getStyle(commandAddition));
323     }
324
325     /*
326      * Support Utilities
327      */

328     public static String JavaDoc getId(IConfigurationElement element) {
329         String JavaDoc id = element.getAttribute(IWorkbenchRegistryConstants.ATT_ID);
330
331         // For sub-menu management -all- items must be id'd so enforce this
332
// here (we could optimize by checking the 'name' of the config
333
// element == "menu"
334
if (id == null || id.length() == 0)
335             id = element.toString();
336
337         return id;
338     }
339
340     static String JavaDoc getName(IConfigurationElement element) {
341         return element.getAttribute(IWorkbenchRegistryConstants.ATT_NAME);
342     }
343
344     static String JavaDoc getLabel(IConfigurationElement element) {
345         return element.getAttribute(IWorkbenchRegistryConstants.ATT_LABEL);
346     }
347
348     static String JavaDoc getMnemonic(IConfigurationElement element) {
349         return element.getAttribute(IWorkbenchRegistryConstants.ATT_MNEMONIC);
350     }
351
352     static String JavaDoc getTooltip(IConfigurationElement element) {
353         return element.getAttribute(IWorkbenchRegistryConstants.ATT_TOOLTIP);
354     }
355
356     static String JavaDoc getIconPath(IConfigurationElement element) {
357         return element.getAttribute(IWorkbenchRegistryConstants.ATT_ICON);
358     }
359
360     static String JavaDoc getDisabledIconPath(IConfigurationElement element) {
361         return element
362                 .getAttribute(IWorkbenchRegistryConstants.ATT_DISABLEDICON);
363     }
364
365     static String JavaDoc getHoverIconPath(IConfigurationElement element) {
366         return element.getAttribute(IWorkbenchRegistryConstants.ATT_HOVERICON);
367     }
368
369     static ImageDescriptor getIconDescriptor(IConfigurationElement element) {
370         String JavaDoc extendingPluginId = element.getDeclaringExtension()
371                 .getContributor().getName();
372
373         String JavaDoc iconPath = getIconPath(element);
374         if (iconPath != null) {
375             return AbstractUIPlugin.imageDescriptorFromPlugin(
376                     extendingPluginId, iconPath);
377         }
378         return null;
379     }
380
381     static ImageDescriptor getDisabledIconDescriptor(
382             IConfigurationElement element) {
383         String JavaDoc extendingPluginId = element.getDeclaringExtension()
384                 .getContributor().getName();
385
386         String JavaDoc iconPath = getDisabledIconPath(element);
387         if (iconPath != null) {
388             return AbstractUIPlugin.imageDescriptorFromPlugin(
389                     extendingPluginId, iconPath);
390         }
391         return null;
392     }
393
394     static ImageDescriptor getHoverIconDescriptor(IConfigurationElement element) {
395         String JavaDoc extendingPluginId = element.getDeclaringExtension()
396                 .getContributor().getName();
397
398         String JavaDoc iconPath = getHoverIconPath(element);
399         if (iconPath != null) {
400             return AbstractUIPlugin.imageDescriptorFromPlugin(
401                     extendingPluginId, iconPath);
402         }
403         return null;
404     }
405
406     public static boolean isSeparatorVisible(IConfigurationElement element) {
407         String JavaDoc val = element
408                 .getAttribute(IWorkbenchRegistryConstants.ATT_VISIBLE);
409         return Boolean.valueOf(val).booleanValue();
410     }
411
412     public static String JavaDoc getClassSpec(IConfigurationElement element) {
413         return element.getAttribute(IWorkbenchRegistryConstants.ATT_CLASS);
414     }
415
416     public static String JavaDoc getCommandId(IConfigurationElement element) {
417         return element.getAttribute(IWorkbenchRegistryConstants.ATT_COMMAND_ID);
418     }
419
420     private int getStyle(IConfigurationElement element) {
421         String JavaDoc style = element
422                 .getAttribute(IWorkbenchRegistryConstants.ATT_STYLE);
423         if (style == null || style.length() == 0) {
424             return CommandContributionItem.STYLE_PUSH;
425         }
426         if (IWorkbenchRegistryConstants.STYLE_TOGGLE.equals(style)) {
427             return CommandContributionItem.STYLE_CHECK;
428         }
429         if (IWorkbenchRegistryConstants.STYLE_RADIO.equals(style)) {
430             return CommandContributionItem.STYLE_RADIO;
431         }
432         if (IWorkbenchRegistryConstants.STYLE_PULLDOWN.equals(style)) {
433             return CommandContributionItem.STYLE_PULLDOWN;
434         }
435         return CommandContributionItem.STYLE_PUSH;
436     }
437
438     /**
439      * @param element
440      * @return A map of parameters names to parameter values. All Strings. The
441      * map may be empty.
442      */

443     public static Map JavaDoc getParameters(IConfigurationElement element) {
444         HashMap JavaDoc map = new HashMap JavaDoc();
445         IConfigurationElement[] parameters = element
446                 .getChildren(IWorkbenchRegistryConstants.TAG_PARAMETER);
447         for (int i = 0; i < parameters.length; i++) {
448             String JavaDoc name = parameters[i]
449                     .getAttribute(IWorkbenchRegistryConstants.ATT_NAME);
450             String JavaDoc value = parameters[i]
451                     .getAttribute(IWorkbenchRegistryConstants.ATT_VALUE);
452             if (name != null && value != null) {
453                 map.put(name, value);
454             }
455         }
456         return map;
457     }
458 }
459
Popular Tags