KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2005, 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.ArrayList JavaDoc;
15 import java.util.Collection 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
22 import org.eclipse.core.commands.Category;
23 import org.eclipse.core.commands.Command;
24 import org.eclipse.core.commands.CommandEvent;
25 import org.eclipse.core.commands.ICommandListener;
26 import org.eclipse.core.commands.IHandler;
27 import org.eclipse.core.commands.ParameterizedCommand;
28 import org.eclipse.core.commands.State;
29 import org.eclipse.core.expressions.Expression;
30 import org.eclipse.core.runtime.IConfigurationElement;
31 import org.eclipse.core.runtime.IExtensionRegistry;
32 import org.eclipse.core.runtime.IRegistryChangeEvent;
33 import org.eclipse.core.runtime.Platform;
34 import org.eclipse.jface.action.Action;
35 import org.eclipse.jface.action.LegacyActionTools;
36 import org.eclipse.jface.bindings.Binding;
37 import org.eclipse.jface.bindings.Scheme;
38 import org.eclipse.jface.bindings.keys.IKeyLookup;
39 import org.eclipse.jface.bindings.keys.KeyBinding;
40 import org.eclipse.jface.bindings.keys.KeyLookupFactory;
41 import org.eclipse.jface.bindings.keys.KeySequence;
42 import org.eclipse.jface.bindings.keys.KeyStroke;
43 import org.eclipse.jface.commands.RadioState;
44 import org.eclipse.jface.commands.ToggleState;
45 import org.eclipse.jface.contexts.IContextIds;
46 import org.eclipse.jface.menus.IMenuStateIds;
47 import org.eclipse.ui.IWorkbenchWindow;
48 import org.eclipse.ui.PlatformUI;
49 import org.eclipse.ui.SelectionEnabler;
50 import org.eclipse.ui.commands.ICommandService;
51 import org.eclipse.ui.handlers.IHandlerActivation;
52 import org.eclipse.ui.handlers.IHandlerService;
53 import org.eclipse.ui.internal.ActionExpression;
54 import org.eclipse.ui.internal.WorkbenchMessages;
55 import org.eclipse.ui.internal.WorkbenchPlugin;
56 import org.eclipse.ui.internal.expressions.LegacyActionExpressionWrapper;
57 import org.eclipse.ui.internal.expressions.LegacyActionSetExpression;
58 import org.eclipse.ui.internal.expressions.LegacyEditorContributionExpression;
59 import org.eclipse.ui.internal.expressions.LegacySelectionEnablerWrapper;
60 import org.eclipse.ui.internal.expressions.LegacyViewContributionExpression;
61 import org.eclipse.ui.internal.expressions.LegacyViewerContributionExpression;
62 import org.eclipse.ui.internal.handlers.ActionDelegateHandlerProxy;
63 import org.eclipse.ui.internal.handlers.IActionCommandMappingService;
64 import org.eclipse.ui.internal.keys.BindingService;
65 import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
66 import org.eclipse.ui.internal.services.RegistryPersistence;
67 import org.eclipse.ui.keys.IBindingService;
68
69 /**
70  * <p>
71  * A static class for reading actions from the registry. Actions were the
72  * mechanism in 3.1 and earlier for contributing to menus and tool bars in the
73  * Eclipse workbench. They have since been replaced with commands.
74  * </p>
75  * <p>
76  * This class is not intended for use outside of the
77  * <code>org.eclipse.ui.workbench</code> plug-in.
78  * </p>
79  *
80  * @since 3.2
81  */

82 public final class LegacyActionPersistence extends RegistryPersistence {
83
84     /**
85      * The index of the action set elements in the indexed array.
86      *
87      * @see LegacyActionPersistence#read()
88      */

89     private static final int INDEX_ACTION_SETS = 0;
90
91     /**
92      * The index of the editor contribution elements in the indexed array.
93      *
94      * @see LegacyActionPersistence#read()
95      */

96     private static final int INDEX_EDITOR_CONTRIBUTIONS = 1;
97
98     /**
99      * The index of the object contribution elements in the indexed array.
100      *
101      * @see LegacyActionPersistence#read()
102      */

103     private static final int INDEX_OBJECT_CONTRIBUTIONS = 2;
104
105     /**
106      * The index of the view contribution elements in the indexed array.
107      *
108      * @see LegacyActionPersistence#read()
109      */

110     private static final int INDEX_VIEW_CONTRIBUTIONS = 3;
111
112     /**
113      * The index of the viewer contribution elements in the indexed array.
114      *
115      * @see LegacyActionPersistence#read()
116      */

117     private static final int INDEX_VIEWER_CONTRIBUTIONS = 4;
118
119
120     /**
121      * Reads the visibility element for a contribution from the
122      * <code>org.eclipse.ui.popupMenus</code> extension point.
123      *
124      * @param parentElement
125      * The contribution element which contains a visibility
126      * expression; must not be <code>null</code>.
127      * @param parentId
128      * The identifier of the parent contribution; may be
129      * <code>null</code>.
130      * @param warningsToLog
131      * The list of warnings to be logged; must not be
132      * <code>null</code>.
133      * @return An expression representing the visibility element; may be
134      * <code>null</code>.
135      */

136     private static final Expression readVisibility(
137             final IConfigurationElement parentElement, final String JavaDoc parentId,
138             final List JavaDoc warningsToLog) {
139         final IConfigurationElement[] visibilityElements = parentElement
140                 .getChildren(TAG_VISIBILITY);
141         if ((visibilityElements == null) || (visibilityElements.length == 0)) {
142             return null;
143         }
144
145         if (visibilityElements.length != 1) {
146             addWarning(warningsToLog,
147                     "There can only be one visibility element", parentElement, //$NON-NLS-1$
148
parentId);
149         }
150
151         final IConfigurationElement visibilityElement = visibilityElements[0];
152         final ActionExpression visibilityActionExpression = new ActionExpression(
153                 visibilityElement);
154         final LegacyActionExpressionWrapper wrapper = new LegacyActionExpressionWrapper(
155                 visibilityActionExpression, null);
156         return wrapper;
157     }
158
159     /**
160      * The binding manager which should be populated with bindings from actions;
161      * must not be <code>null</code>.
162      */

163     private final BindingService bindingService;
164
165
166
167     /**
168      * The command service which is providing the commands for the workbench;
169      * must not be <code>null</code>.
170      */

171     private final ICommandService commandService;
172
173     /**
174      * The handler activations that have come from the registry. This is used to
175      * flush the activations when the registry is re-read. This value is never
176      * <code>null</code>
177      */

178     private final Collection JavaDoc handlerActivations = new ArrayList JavaDoc();
179
180     /**
181      * The menu contributions that have come from the registry. This is used to
182      * flush the contributions when the registry is re-read. This value is never
183      * <code>null</code>
184      */

185     private final Collection JavaDoc menuContributions = new ArrayList JavaDoc();
186
187     /**
188      * The service locator from which services can be retrieved in the future;
189      * must not be <code>null</code>.
190      */

191     private final IWorkbenchWindow window;
192     
193     /**
194      * Help action sets with enable/disable.
195      */

196     private ICommandListener actionSetListener = new ICommandListener() {
197         public void commandChanged(CommandEvent commandEvent) {
198             Command cmd = commandEvent.getCommand();
199             String JavaDoc commandId = cmd.getId();
200             Binding binding = (Binding) commandIdToBinding.get(commandId);
201             if (binding != null) {
202                 if (cmd.isEnabled()) {
203                     if (!actionSetActiveBindings.contains(binding)) {
204                         bindingService.addBinding(binding);
205                         actionSetActiveBindings.add(binding);
206                     }
207                 } else if (actionSetActiveBindings.contains(binding)) {
208                     bindingService.removeBinding(binding);
209                     actionSetActiveBindings.remove(binding);
210                 }
211             }
212         }
213     };
214     
215     /**
216      * Map every commandId to its binding.
217      */

218     private HashMap JavaDoc commandIdToBinding = new HashMap JavaDoc();
219     
220     /**
221      * Which bindings do we currently have outstanding.
222      */

223     private HashSet JavaDoc actionSetActiveBindings = new HashSet JavaDoc();
224
225     /**
226      * Constructs a new instance of {@link LegacyActionPersistence}.
227      *
228      * @param window
229      * The window from which the services should be retrieved; must
230      * not be <code>null</code>.
231      */

232     public LegacyActionPersistence(final IWorkbenchWindow window) {
233         // TODO Blind casts are bad.
234
this.bindingService = (BindingService) window
235                 .getService(IBindingService.class);
236
237         this.commandService = (ICommandService) window
238                 .getService(ICommandService.class);
239         this.window = window;
240     }
241
242     /**
243      * Deactivates all of the activations made by this class, and then clears
244      * the collection. This should be called before every read.
245      */

246     private final void clearActivations() {
247         final IHandlerService service = (IHandlerService) window
248                 .getService(IHandlerService.class);
249         service.deactivateHandlers(handlerActivations);
250         final Iterator JavaDoc activationItr = handlerActivations.iterator();
251         while (activationItr.hasNext()) {
252             final IHandlerActivation activation = (IHandlerActivation) activationItr
253                     .next();
254             final IHandler handler = activation.getHandler();
255             if (handler != null) {
256                 handler.dispose();
257             }
258         }
259         handlerActivations.clear();
260     }
261
262     /**
263      * Removes all of the bindings made by this class, and then clears the
264      * collection. This should be called before every read.
265      */

266     private final void clearBindings() {
267         Iterator JavaDoc i = commandIdToBinding.entrySet().iterator();
268         while (i.hasNext()) {
269             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) i.next();
270             String JavaDoc commandId = (String JavaDoc) entry.getKey();
271             Binding binding = (Binding) entry.getValue();
272             commandService.getCommand(commandId).removeCommandListener(actionSetListener);
273             if (binding!=null && actionSetActiveBindings.contains(binding)) {
274                 bindingService.removeBinding(binding);
275             }
276         }
277         commandIdToBinding.clear();
278         actionSetActiveBindings.clear();
279     }
280
281     /**
282      * Removes all of the image bindings made by this class, and then clears the
283      * collection. This should be called before every read.
284      *
285      */

286     private final void clearImages() {
287         // TODO Implement
288
}
289
290     /**
291      * Removes all of the contributions made by this class, and then clears the
292      * collection. This should be called before every read.
293      */

294     private final void clearMenus() {
295         menuContributions.clear();
296     }
297
298     /**
299      * Extracts any key bindings from the action. If such a binding exists, it
300      * is added to the binding manager.
301      *
302      * @param element
303      * The action from which the binding should be read; must not be
304      * <code>null</code>.
305      * @param command
306      * The fully-parameterized command for which a binding should be
307      * made; must not be <code>null</code>.
308      */

309     private final void convertActionToBinding(
310             final IConfigurationElement element,
311             final ParameterizedCommand command, final List JavaDoc warningsToLog) {
312         // Figure out which accelerator text to use.
313
String JavaDoc acceleratorText = readOptional(element, ATT_ACCELERATOR);
314         if (acceleratorText == null) {
315             final String JavaDoc label = readOptional(element, ATT_LABEL);
316             if (label != null) {
317                 acceleratorText = LegacyActionTools
318                         .extractAcceleratorText(label);
319             }
320         }
321
322         // If there is some accelerator text, generate a key sequence from it.
323
if (acceleratorText != null) {
324             final IKeyLookup lookup = KeyLookupFactory.getSWTKeyLookup();
325             final int acceleratorInt = LegacyActionTools
326                     .convertAccelerator(acceleratorText);
327             final int modifierMask = lookup.getAlt() | lookup.getCommand()
328                     | lookup.getCtrl() | lookup.getShift();
329             final int modifierKeys = acceleratorInt & modifierMask;
330             final int naturalKey = acceleratorInt & ~modifierMask;
331             final KeyStroke keyStroke = KeyStroke.getInstance(modifierKeys,
332                     naturalKey);
333             final KeySequence keySequence = KeySequence.getInstance(keyStroke);
334
335             final Scheme activeScheme = bindingService.getActiveScheme();
336
337             try {
338                 final Binding binding = new KeyBinding(keySequence, command,
339                         activeScheme.getId(), IContextIds.CONTEXT_ID_WINDOW,
340                         null, null, null, Binding.SYSTEM);
341                 commandIdToBinding.put(command.getCommand().getId(), binding);
342
343                 if (command.getCommand().isEnabled()) {
344                     bindingService.addBinding(binding);
345                     actionSetActiveBindings.add(binding);
346                 }
347
348                 command.getCommand().addCommandListener(actionSetListener);
349             } catch (IllegalArgumentException JavaDoc e) {
350                 addWarning(warningsToLog,
351                         "invalid keybinding: " + e.getMessage(), element, //$NON-NLS-1$
352
command.getCommand().getId());
353             }
354         }
355     }
356
357     /**
358      * Determine which command to use. This is slightly complicated as actions
359      * do not have to have commands, but the new architecture requires it. As
360      * such, we will auto-generate a command for the action if the definitionId
361      * is missing or points to a command that does not yet exist. All such
362      * command identifiers are prefixed with AUTOGENERATED_COMMAND_ID_PREFIX.
363      *
364      * @param element
365      * The action element from which a command must be generated;
366      * must not be <code>null</code>.
367      * @param primaryId
368      * The primary identifier to use when auto-generating a command;
369      * must not be <code>null</code>.
370      * @param secondaryId
371      * The secondary identifier to use when auto-generating a
372      * command; must not be <code>null</code>.
373      * @param warningsToLog
374      * The collection of warnings logged while reading the extension
375      * point; must not be <code>null</code>.
376      * @return the fully-parameterized command; <code>null</code> if an error
377      * occurred.
378      */

379     private final ParameterizedCommand convertActionToCommand(
380             final IConfigurationElement element, final String JavaDoc primaryId,
381             final String JavaDoc secondaryId, final List JavaDoc warningsToLog) {
382         String JavaDoc commandId = readOptional(element, ATT_DEFINITION_ID);
383         Command command = null;
384         if (commandId != null) {
385             command = commandService.getCommand(commandId);
386         }
387
388         final IActionCommandMappingService mappingService = (IActionCommandMappingService) window
389                 .getService(IActionCommandMappingService.class);
390         
391         String JavaDoc label = null;
392         if ((commandId == null) || (!command.isDefined())) {
393             // Add a mapping from this action id to the command id.
394
if (commandId == null && mappingService != null) {
395                 commandId = mappingService.getGeneratedCommandId(primaryId,
396                         secondaryId);
397             }
398             if (commandId == null) {
399                 WorkbenchPlugin.log("MappingService unavailable"); //$NON-NLS-1$
400
return null;
401             }
402
403             // Read the label attribute.
404
label = readRequired(element, ATT_LABEL, warningsToLog,
405                     "Actions require a non-empty label or definitionId", //$NON-NLS-1$
406
commandId);
407             if (label == null) {
408                 label = WorkbenchMessages.LegacyActionPersistence_AutogeneratedCommandName;
409             }
410
411             /*
412              * Read the tooltip attribute. The tooltip is really the description
413              * of the command.
414              */

415             final String JavaDoc tooltip = readOptional(element, ATT_TOOLTIP);
416
417             // Define the command.
418
command = commandService.getCommand(commandId);
419             final Category category = commandService.getCategory(null);
420             final String JavaDoc name = LegacyActionTools.removeAcceleratorText(Action
421                     .removeMnemonics(label));
422             command.define(name, tooltip, category, null);
423
424             // TODO Decide the command state.
425
final String JavaDoc style = readOptional(element, ATT_STYLE);
426             if (STYLE_RADIO.equals(style)) {
427                 final State state = new RadioState();
428                 // TODO How to set the id?
429
final boolean checked = readBoolean(element, ATT_STATE, false);
430                 state.setValue((checked) ? Boolean.TRUE : Boolean.FALSE);
431                 command.addState(IMenuStateIds.STYLE, state);
432
433             } else if (STYLE_TOGGLE.equals(style)) {
434                 final State state = new ToggleState();
435                 final boolean checked = readBoolean(element, ATT_STATE, false);
436                 state.setValue((checked) ? Boolean.TRUE : Boolean.FALSE);
437                 command.addState(IMenuStateIds.STYLE, state);
438             }
439         }
440         // this allows us to look up a "commandId" give the contributionId
441
// and the actionId
442
if (mappingService != null && commandId != null) {
443             mappingService.map(mappingService.getGeneratedCommandId(primaryId,
444                     secondaryId), commandId);
445         }
446
447         return new ParameterizedCommand(command, null);
448     }
449
450     /**
451      * <p>
452      * Extracts the handler information from the given action element. These are
453      * registered with the handler service. They are always active.
454      * </p>
455      *
456      * @param element
457      * The action element from which the handler should be read; must
458      * not be <code>null</code>.
459      * @param actionId
460      * The identifier of the action for which a handler is being
461      * created; must not be <code>null</code>.
462      * @param command
463      * The command for which this handler applies; must not be
464      * <code>null</code>.
465      * @param activeWhenExpression
466      * The expression controlling when the handler is active; may be
467      * <code>null</code>.
468      * @param viewId
469      * The view to which this handler is associated. This value is
470      * required if this is a view action; otherwise it can be
471      * <code>null</code>.
472      * @param warningsToLog
473      * The collection of warnings while parsing this extension point;
474      * must not be <code>null</code>.
475      */

476     private final void convertActionToHandler(
477             final IConfigurationElement element, final String JavaDoc actionId,
478             final ParameterizedCommand command,
479             final Expression activeWhenExpression, final String JavaDoc viewId,
480             final List JavaDoc warningsToLog) {
481         // Check to see if this is a retargettable action.
482
final boolean retarget = readBoolean(element, ATT_RETARGET, false);
483
484         final boolean classAvailable = (element.getAttribute(ATT_CLASS) != null)
485                 || (element.getChildren(TAG_CLASS).length != 0);
486         // Read the class attribute.
487
String JavaDoc classString = readOptional(element, ATT_CLASS);
488         if (classAvailable && classString == null) {
489             classString = readOptional(element.getChildren(TAG_CLASS)[0],
490                     ATT_CLASS);
491         }
492
493         if (retarget) {
494             if (classAvailable && !isPulldown(element)) {
495                 addWarning(warningsToLog,
496                         "The class was not null but retarget was set to true", //$NON-NLS-1$
497
element, actionId, ATT_CLASS, classString);
498             }
499
500             // Add a mapping from this action id to the command id.
501
final IActionCommandMappingService mappingService = (IActionCommandMappingService) window
502                     .getService(IActionCommandMappingService.class);
503             if (mappingService != null) {
504                 mappingService.map(actionId, command.getId());
505             } else {
506                 // this is probably the shutdown case where the service has
507
// already disposed.
508
addWarning(
509                         warningsToLog,
510                         "Retarget service unavailable", //$NON-NLS-1$
511
element, actionId);
512             }
513             return; // This is nothing more to be done.
514

515         } else if (!classAvailable) {
516             addWarning(
517                     warningsToLog,
518                     "There was no class provided, and the action is not retargettable", //$NON-NLS-1$
519
element, actionId);
520             return; // There is nothing to be done.
521
}
522
523         // Read the enablesFor attribute, and enablement and selection elements.
524
SelectionEnabler enabler = null;
525         if (element.getAttribute(ATT_ENABLES_FOR) != null) {
526             enabler = new SelectionEnabler(element);
527         } else {
528             IConfigurationElement[] kids = element.getChildren(TAG_ENABLEMENT);
529             if (kids.length > 0) {
530                 enabler = new SelectionEnabler(element);
531             }
532         }
533         final Expression enabledWhenExpression;
534         if (enabler == null) {
535             enabledWhenExpression = null;
536         } else {
537             enabledWhenExpression = new LegacySelectionEnablerWrapper(enabler,
538                     window);
539         }
540
541         /*
542          * Create the handler. TODO The image style is read at the workbench
543          * level, but it is hard to communicate this information to this point.
544          * For now, I'll pass null, but this ultimately won't work.
545          */

546         final ActionDelegateHandlerProxy handler = new ActionDelegateHandlerProxy(
547                 element, ATT_CLASS, actionId, command, window, null,
548                 enabledWhenExpression, viewId);
549
550         // Read the help context id.
551
final String JavaDoc helpContextId = readOptional(element, ATT_HELP_CONTEXT_ID);
552         if (helpContextId != null) {
553             commandService.setHelpContextId(handler, helpContextId);
554         }
555
556         // Activate the handler.
557
final String JavaDoc commandId = command.getId();
558         final IHandlerService service = (IHandlerService) window
559                 .getService(IHandlerService.class);
560         final IHandlerActivation handlerActivation;
561         if (activeWhenExpression == null) {
562             handlerActivation = service.activateHandler(commandId, handler);
563         } else {
564             handlerActivation = service.activateHandler(commandId, handler,
565                     activeWhenExpression);
566         }
567         handlerActivations.add(handlerActivation);
568     }
569
570
571
572     public final void dispose() {
573         super.dispose();
574         clear();
575     }
576
577     private void clear() {
578         clearActivations();
579         clearBindings();
580         clearImages();
581         clearMenus();
582     }
583
584     protected final boolean isChangeImportant(final IRegistryChangeEvent event) {
585         return !((event.getExtensionDeltas(PlatformUI.PLUGIN_ID,
586                 IWorkbenchRegistryConstants.PL_ACTION_SETS).length == 0)
587                 && (event.getExtensionDeltas(PlatformUI.PLUGIN_ID,
588                         IWorkbenchRegistryConstants.PL_EDITOR_ACTIONS).length == 0)
589                 && (event.getExtensionDeltas(PlatformUI.PLUGIN_ID,
590                         IWorkbenchRegistryConstants.PL_POPUP_MENU).length == 0) && (event
591                 .getExtensionDeltas(PlatformUI.PLUGIN_ID,
592                         IWorkbenchRegistryConstants.PL_VIEW_ACTIONS).length == 0));
593     }
594
595     /**
596      * <p>
597      * Reads all of the actions from the deprecated extension points. Actions
598      * have been replaced with commands, command images, handlers, menu elements
599      * and action sets.
600      * </p>
601      * <p>
602      * TODO Before this method is called, all of the extension points must be
603      * cleared.
604      * </p>
605      */

606     public final void read() {
607         clear();
608         LegacyActionPersistence.super.read();
609
610         // Create the extension registry mementos.
611
final IExtensionRegistry registry = Platform.getExtensionRegistry();
612         int actionSetCount = 0;
613         int editorContributionCount = 0;
614         int objectContributionCount = 0;
615         int viewContributionCount = 0;
616         int viewerContributionCount = 0;
617         final IConfigurationElement[][] indexedConfigurationElements = new IConfigurationElement[5][];
618
619         // Sort the actionSets extension point.
620
final IConfigurationElement[] actionSetsExtensionPoint = registry
621                 .getConfigurationElementsFor(EXTENSION_ACTION_SETS);
622         for (int i = 0; i < actionSetsExtensionPoint.length; i++) {
623             final IConfigurationElement element = actionSetsExtensionPoint[i];
624             final String JavaDoc name = element.getName();
625             if (TAG_ACTION_SET.equals(name)) {
626                 addElementToIndexedArray(element, indexedConfigurationElements,
627                         INDEX_ACTION_SETS, actionSetCount++);
628             }
629         }
630
631         // Sort the editorActions extension point.
632
final IConfigurationElement[] editorActionsExtensionPoint = registry
633                 .getConfigurationElementsFor(EXTENSION_EDITOR_ACTIONS);
634         for (int i = 0; i < editorActionsExtensionPoint.length; i++) {
635             final IConfigurationElement element = editorActionsExtensionPoint[i];
636             final String JavaDoc name = element.getName();
637             if (TAG_EDITOR_CONTRIBUTION.equals(name)) {
638                 addElementToIndexedArray(element, indexedConfigurationElements,
639                         INDEX_EDITOR_CONTRIBUTIONS, editorContributionCount++);
640             }
641         }
642
643         // Sort the popupMenus extension point.
644
final IConfigurationElement[] popupMenusExtensionPoint = registry
645                 .getConfigurationElementsFor(EXTENSION_POPUP_MENUS);
646         for (int i = 0; i < popupMenusExtensionPoint.length; i++) {
647             final IConfigurationElement element = popupMenusExtensionPoint[i];
648             final String JavaDoc name = element.getName();
649             if (TAG_OBJECT_CONTRIBUTION.equals(name)) {
650                 addElementToIndexedArray(element, indexedConfigurationElements,
651                         INDEX_OBJECT_CONTRIBUTIONS, objectContributionCount++);
652             } else if (TAG_VIEWER_CONTRIBUTION.equals(name)) {
653                 addElementToIndexedArray(element, indexedConfigurationElements,
654                         INDEX_VIEWER_CONTRIBUTIONS, viewerContributionCount++);
655             }
656         }
657
658         // Sort the viewActions extension point.
659
final IConfigurationElement[] viewActionsExtensionPoint = registry
660                 .getConfigurationElementsFor(EXTENSION_VIEW_ACTIONS);
661         for (int i = 0; i < viewActionsExtensionPoint.length; i++) {
662             final IConfigurationElement element = viewActionsExtensionPoint[i];
663             final String JavaDoc name = element.getName();
664             if (TAG_VIEW_CONTRIBUTION.equals(name)) {
665                 addElementToIndexedArray(element, indexedConfigurationElements,
666                         INDEX_VIEW_CONTRIBUTIONS, viewContributionCount++);
667             }
668         }
669
670         readActionSets(indexedConfigurationElements[INDEX_ACTION_SETS],
671                 actionSetCount);
672         readEditorContributions(
673                 indexedConfigurationElements[INDEX_EDITOR_CONTRIBUTIONS],
674                 editorContributionCount);
675         readObjectContributions(
676                 indexedConfigurationElements[INDEX_OBJECT_CONTRIBUTIONS],
677                 objectContributionCount);
678         readViewContributions(
679                 indexedConfigurationElements[INDEX_VIEW_CONTRIBUTIONS],
680                 viewContributionCount);
681         readViewerContributions(
682                 indexedConfigurationElements[INDEX_VIEWER_CONTRIBUTIONS],
683                 viewerContributionCount);
684         
685     }
686
687     /**
688      * Reads the actions, and defines all the necessary subcomponents in terms
689      * of the command architecture. For each action, there could be a command, a
690      * command image binding, a handler and a menu item.
691      *
692      * @param primaryId
693      * The identifier of the primary object to which this action
694      * belongs. This is used to auto-generate command identifiers
695      * when required. The <code>primaryId</code> must not be
696      * <code>null</code>.
697      * @param elements
698      * The action elements to be read; must not be <code>null</code>.
699      * @param warningsToLog
700      * The collection of warnings while parsing this extension point;
701      * must not be <code>null</code>.
702      * @param visibleWhenExpression
703      * The expression controlling visibility of the corresponding
704      * menu elements; may be <code>null</code>.
705      * @param viewId
706      * The view to which this handler is associated. This value is
707      * required if this is a view action; otherwise it can be
708      * <code>null</code>.
709      * @return References to the created menu elements; may be <code>null</code>,
710      * and may be empty.
711      */

712     private final void readActions(final String JavaDoc primaryId,
713             final IConfigurationElement[] elements, final List JavaDoc warningsToLog,
714             final Expression visibleWhenExpression, final String JavaDoc viewId) {
715         for (int i = 0; i < elements.length; i++) {
716             final IConfigurationElement element = elements[i];
717
718             /*
719              * We might need the identifier to generate the command, so we'll
720              * read it out now.
721              */

722             final String JavaDoc id = readRequired(element, ATT_ID, warningsToLog,
723                     "Actions require an id"); //$NON-NLS-1$
724
if (id == null) {
725                 continue;
726             }
727
728             // Try to break out the command part of the action.
729
final ParameterizedCommand command = convertActionToCommand(
730                     element, primaryId, id, warningsToLog);
731             if (command == null) {
732                 continue;
733             }
734
735             convertActionToHandler(element, id, command, visibleWhenExpression,
736                     viewId, warningsToLog);
737             // TODO Read the overrideActionId attribute
738

739             convertActionToBinding(element, command, warningsToLog);
740
741         }
742     }
743
744     /**
745      * Reads all of the action and menu child elements from the given element.
746      *
747      * @param element
748      * The configuration element from which the actions and menus
749      * should be read; must not be <code>null</code>, but may be
750      * empty.
751      * @param id
752      * The identifier of the contribution being made. This could be
753      * an action set, an editor contribution, a view contribution, a
754      * viewer contribution or an object contribution. This value must
755      * not be <code>null</code>.
756      * @param warningsToLog
757      * The list of warnings already logged for this extension point;
758      * must not be <code>null</code>.
759      * @param visibleWhenExpression
760      * The expression controlling visibility of the corresponding
761      * menu elements; may be <code>null</code>.
762      * @param viewId
763      * The view to which this handler is associated. This value is
764      * required if this is a view action; otherwise it can be
765      * <code>null</code>.
766      * @return An array of references to the created menu elements. This value
767      * may be <code>null</code> if there was a problem parsing the
768      * configuration element.
769      */

770     private final void readActionsAndMenus(
771             final IConfigurationElement element, final String JavaDoc id,
772             final List JavaDoc warningsToLog,
773             final Expression visibleWhenExpression, final String JavaDoc viewId) {
774
775         // Read its child elements.
776
final IConfigurationElement[] actionElements = element
777                 .getChildren(TAG_ACTION);
778         readActions(id, actionElements,
779                 warningsToLog, visibleWhenExpression, viewId);
780
781     }
782
783     /**
784      * Reads the deprecated actions from an array of elements from the action
785      * sets extension point.
786      *
787      * @param configurationElements
788      * The configuration elements in the extension point; must not be
789      * <code>null</code>, but may be empty.
790      * @param configurationElementCount
791      * The number of configuration elements that are really in the
792      * array.
793      */

794     private final void readActionSets(
795             final IConfigurationElement[] configurationElements,
796             final int configurationElementCount) {
797         //
798
// this was an even dumber fix than modifying the path
799
//
800
// stupid navigate group
801
// SGroup nav = menuService.getGroup(STUPID_NAVIGATE);
802
// if (!nav.isDefined()) {
803
// nav.define(new SLocation(new SBar(SBar.TYPE_MENU, null)));
804
// }
805
// stupid navigate group
806

807         final List JavaDoc warningsToLog = new ArrayList JavaDoc(1);
808
809         for (int i = 0; i < configurationElementCount; i++) {
810             final IConfigurationElement element = configurationElements[i];
811
812             // Read the action set identifier.
813
final String JavaDoc id = readRequired(element, ATT_ID, warningsToLog,
814                     "Action sets need an id"); //$NON-NLS-1$
815
if (id == null) {
816                 continue;
817             }
818
819             // Read the label.
820
final String JavaDoc label = readRequired(element, ATT_LABEL,
821                     warningsToLog, "Actions set need a label", //$NON-NLS-1$
822
id);
823             if (label == null) {
824                 continue;
825             }
826
827             // Restrict the handler to when the action set is active.
828
final LegacyActionSetExpression expression = new LegacyActionSetExpression(
829                     id, window);
830
831
832             // Read all of the child elements.
833
readActionsAndMenus(element, id,
834                     warningsToLog, expression, null);
835             // Define the action set.
836
}
837
838         logWarnings(
839                 warningsToLog,
840                 "Warnings while parsing the action sets from the 'org.eclipse.ui.actionSets' extension point"); //$NON-NLS-1$
841
}
842
843     /**
844      * Reads the deprecated editor contributions from an array of elements from
845      * the editor actions extension point.
846      *
847      * @param configurationElements
848      * The configuration elements in the extension point; must not be
849      * <code>null</code>, but may be empty.
850      * @param configurationElementCount
851      * The number of configuration elements that are really in the
852      * array.
853      */

854     private final void readEditorContributions(
855             final IConfigurationElement[] configurationElements,
856             final int configurationElementCount) {
857         final List JavaDoc warningsToLog = new ArrayList JavaDoc(1);
858
859         for (int i = 0; i < configurationElementCount; i++) {
860             final IConfigurationElement element = configurationElements[i];
861
862             // Read the editor contribution identifier.
863
final String JavaDoc id = readRequired(element, ATT_ID, warningsToLog,
864                     "Editor contributions need an id"); //$NON-NLS-1$
865
if (id == null) {
866                 continue;
867             }
868
869             /*
870              * Read the target id. This is the identifier of the editor with
871              * which these contributions are associated.
872              */

873             final String JavaDoc targetId = readRequired(element, ATT_TARGET_ID,
874                     warningsToLog, "Editor contributions need a target id", id); //$NON-NLS-1$
875
if (targetId == null) {
876                 continue;
877             }
878             final Expression visibleWhenExpression = new LegacyEditorContributionExpression(
879                     targetId, window);
880
881             // Read all of the child elements from the registry.
882
readActionsAndMenus(element, id, warningsToLog,
883                     visibleWhenExpression, null);
884         }
885
886         logWarnings(
887                 warningsToLog,
888                 "Warnings while parsing the editor contributions from the 'org.eclipse.ui.editorActions' extension point"); //$NON-NLS-1$
889
}
890
891
892
893
894     /**
895      * Reads the deprecated object contributions from an array of elements from
896      * the popup menus extension point.
897      *
898      * @param configurationElements
899      * The configuration elements in the extension point; must not be
900      * <code>null</code>, but may be empty.
901      * @param configurationElementCount
902      * The number of configuration elements that are really in the
903      * array.
904      */

905     private final void readObjectContributions(
906             final IConfigurationElement[] configurationElements,
907             final int configurationElementCount) {
908         final List JavaDoc warningsToLog = new ArrayList JavaDoc(1);
909
910         for (int i = 0; i < configurationElementCount; i++) {
911             final IConfigurationElement element = configurationElements[i];
912
913             // Read the object contribution identifier.
914
final String JavaDoc id = readRequired(element, ATT_ID, warningsToLog,
915                     "Object contributions need an id"); //$NON-NLS-1$
916
if (id == null) {
917                 continue;
918             }
919
920             // Read the object class. This influences the visibility.
921
final String JavaDoc objectClass = readRequired(element, ATT_OBJECTCLASS,
922                     warningsToLog,
923                     "Object contributions need an object class", id); //$NON-NLS-1$
924
if (objectClass == null) {
925                 continue;
926             }
927
928             // TODO Read the name filter. This influences the visibility.
929
// final String nameFilter = readOptional(element,
930
// ATT_NAME_FILTER);
931

932             // TODO Read the object class. This influences the visibility.
933
// final boolean adaptable = readBoolean(element,
934
// ATT_ADAPTABLE,
935
// false);
936

937
938             // TODO Read the filter elements.
939
// TODO Read the enablement elements.
940

941             // TODO Figure out an appropriate visibility expression.
942
// Read the visibility element, if any.
943
final Expression visibleWhenExpression = readVisibility(element,
944                     id, warningsToLog);
945
946             // Read all of the child elements from the registry.
947
readActionsAndMenus(element, id, warningsToLog,
948                     visibleWhenExpression, null);
949         }
950
951         logWarnings(
952                 warningsToLog,
953                 "Warnings while parsing the object contributions from the 'org.eclipse.ui.popupMenus' extension point"); //$NON-NLS-1$
954
}
955
956     /**
957      * Reads the deprecated view contributions from an array of elements from
958      * the view actions extension point.
959      *
960      * @param configurationElements
961      * The configuration elements in the extension point; must not be
962      * <code>null</code>, but may be empty.
963      * @param configurationElementCount
964      * The number of configuration elements that are really in the
965      * array.
966      */

967     private final void readViewContributions(
968             final IConfigurationElement[] configurationElements,
969             final int configurationElementCount) {
970         final List JavaDoc warningsToLog = new ArrayList JavaDoc(1);
971
972         for (int i = 0; i < configurationElementCount; i++) {
973             final IConfigurationElement element = configurationElements[i];
974
975             // Read the view contribution identifier.
976
final String JavaDoc id = readRequired(element, ATT_ID, warningsToLog,
977                     "View contributions need an id"); //$NON-NLS-1$
978
if (id == null) {
979                 continue;
980             }
981
982             /*
983              * Read the target id. This is the identifier of the view with which
984              * these contributions are associated.
985              */

986             final String JavaDoc targetId = readRequired(element, ATT_TARGET_ID,
987                     warningsToLog, "View contributions need a target id", id); //$NON-NLS-1$
988
if (targetId == null) {
989                 continue;
990             }
991             final Expression visibleWhenExpression = new LegacyViewContributionExpression(
992                     targetId, window);
993
994             // Read all of the child elements from the registry.
995
readActionsAndMenus(element, id, warningsToLog,
996                     visibleWhenExpression, targetId);
997         }
998
999         logWarnings(
1000                warningsToLog,
1001                "Warnings while parsing the view contributions from the 'org.eclipse.ui.viewActions' extension point"); //$NON-NLS-1$
1002
}
1003
1004    /**
1005     * Reads the deprecated viewer contributions from an array of elements from
1006     * the popup menus extension point.
1007     *
1008     * @param configurationElements
1009     * The configuration elements in the extension point; must not be
1010     * <code>null</code>, but may be empty.
1011     * @param configurationElementCount
1012     * The number of configuration elements that are really in the
1013     * array.
1014     */

1015    private final void readViewerContributions(
1016            final IConfigurationElement[] configurationElements,
1017            final int configurationElementCount) {
1018        final List JavaDoc warningsToLog = new ArrayList JavaDoc(1);
1019
1020        for (int i = 0; i < configurationElementCount; i++) {
1021            final IConfigurationElement element = configurationElements[i];
1022
1023            // Read the viewer contribution identifier.
1024
final String JavaDoc id = readRequired(element, ATT_ID, warningsToLog,
1025                    "Viewer contributions need an id"); //$NON-NLS-1$
1026
if (id == null) {
1027                continue;
1028            }
1029
1030            /*
1031             * Read the target id. This is the identifier of the view with which
1032             * these contributions are associated.
1033             */

1034            final String JavaDoc targetId = readRequired(element, ATT_TARGET_ID,
1035                    warningsToLog, "Viewer contributions need a target id", id); //$NON-NLS-1$
1036
if (targetId == null) {
1037                continue;
1038            }
1039
1040            // Read the visibility element, if any.
1041
final Expression visibleWhenExpression = readVisibility(element,
1042                    id, warningsToLog);
1043            final Expression menuVisibleWhenExpression = new LegacyViewerContributionExpression(
1044                    targetId, window, visibleWhenExpression);
1045
1046            // Read all of the child elements from the registry.
1047
readActionsAndMenus(element, id, warningsToLog,
1048                    menuVisibleWhenExpression, targetId);
1049        }
1050
1051        logWarnings(
1052                warningsToLog,
1053                "Warnings while parsing the viewer contributions from the 'org.eclipse.ui.popupMenus' extension point"); //$NON-NLS-1$
1054
}
1055}
1056
Popular Tags