Package org.eclipse.ui.internal.menus

Source Code of org.eclipse.ui.internal.menus.LegacyActionPersistence

/*******************************************************************************
* Copyright (c) 2005, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*******************************************************************************/

package org.eclipse.ui.internal.menus;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.commands.Category;
import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.CommandEvent;
import org.eclipse.core.commands.ICommandListener;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.commands.State;
import org.eclipse.core.expressions.Expression;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IRegistryChangeEvent;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.LegacyActionTools;
import org.eclipse.jface.bindings.Binding;
import org.eclipse.jface.bindings.Scheme;
import org.eclipse.jface.bindings.keys.IKeyLookup;
import org.eclipse.jface.bindings.keys.KeyBinding;
import org.eclipse.jface.bindings.keys.KeyLookupFactory;
import org.eclipse.jface.bindings.keys.KeySequence;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.commands.RadioState;
import org.eclipse.jface.commands.ToggleState;
import org.eclipse.jface.contexts.IContextIds;
import org.eclipse.jface.menus.IMenuStateIds;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.SelectionEnabler;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.handlers.IHandlerActivation;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.internal.ActionExpression;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.expressions.LegacyActionExpressionWrapper;
import org.eclipse.ui.internal.expressions.LegacyActionSetExpression;
import org.eclipse.ui.internal.expressions.LegacyEditorContributionExpression;
import org.eclipse.ui.internal.expressions.LegacySelectionEnablerWrapper;
import org.eclipse.ui.internal.expressions.LegacyViewContributionExpression;
import org.eclipse.ui.internal.expressions.LegacyViewerContributionExpression;
import org.eclipse.ui.internal.handlers.ActionDelegateHandlerProxy;
import org.eclipse.ui.internal.handlers.IActionCommandMappingService;
import org.eclipse.ui.internal.keys.BindingService;
import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
import org.eclipse.ui.internal.services.RegistryPersistence;
import org.eclipse.ui.keys.IBindingService;

/**
* <p>
* A static class for reading actions from the registry. Actions were the
* mechanism in 3.1 and earlier for contributing to menus and tool bars in the
* Eclipse workbench. They have since been replaced with commands.
* </p>
* <p>
* This class is not intended for use outside of the
* <code>org.eclipse.ui.workbench</code> plug-in.
* </p>
*
* @since 3.2
*/
public final class LegacyActionPersistence extends RegistryPersistence {

  /**
   * The index of the action set elements in the indexed array.
   *
   * @see LegacyActionPersistence#read()
   */
  private static final int INDEX_ACTION_SETS = 0;

  /**
   * The index of the editor contribution elements in the indexed array.
   *
   * @see LegacyActionPersistence#read()
   */
  private static final int INDEX_EDITOR_CONTRIBUTIONS = 1;

  /**
   * The index of the object contribution elements in the indexed array.
   *
   * @see LegacyActionPersistence#read()
   */
  private static final int INDEX_OBJECT_CONTRIBUTIONS = 2;

  /**
   * The index of the view contribution elements in the indexed array.
   *
   * @see LegacyActionPersistence#read()
   */
  private static final int INDEX_VIEW_CONTRIBUTIONS = 3;

  /**
   * The index of the viewer contribution elements in the indexed array.
   *
   * @see LegacyActionPersistence#read()
   */
  private static final int INDEX_VIEWER_CONTRIBUTIONS = 4;


  /**
   * Reads the visibility element for a contribution from the
   * <code>org.eclipse.ui.popupMenus</code> extension point.
   *
   * @param parentElement
   *            The contribution element which contains a visibility
   *            expression; must not be <code>null</code>.
   * @param parentId
   *            The identifier of the parent contribution; may be
   *            <code>null</code>.
   * @param warningsToLog
   *            The list of warnings to be logged; must not be
   *            <code>null</code>.
   * @return An expression representing the visibility element; may be
   *         <code>null</code>.
   */
  private static final Expression readVisibility(
      final IConfigurationElement parentElement, final String parentId,
      final List warningsToLog) {
    final IConfigurationElement[] visibilityElements = parentElement
        .getChildren(TAG_VISIBILITY);
    if ((visibilityElements == null) || (visibilityElements.length == 0)) {
      return null;
    }

    if (visibilityElements.length != 1) {
      addWarning(warningsToLog,
          "There can only be one visibility element", parentElement, //$NON-NLS-1$
          parentId);
    }

    final IConfigurationElement visibilityElement = visibilityElements[0];
    final ActionExpression visibilityActionExpression = new ActionExpression(
        visibilityElement);
    final LegacyActionExpressionWrapper wrapper = new LegacyActionExpressionWrapper(
        visibilityActionExpression, null);
    return wrapper;
  }

  /**
   * The binding manager which should be populated with bindings from actions;
   * must not be <code>null</code>.
   */
  private final BindingService bindingService;



  /**
   * The command service which is providing the commands for the workbench;
   * must not be <code>null</code>.
   */
  private final ICommandService commandService;

  /**
   * The handler activations that have come from the registry. This is used to
   * flush the activations when the registry is re-read. This value is never
   * <code>null</code>
   */
  private final Collection handlerActivations = new ArrayList();

  /**
   * The menu contributions that have come from the registry. This is used to
   * flush the contributions when the registry is re-read. This value is never
   * <code>null</code>
   */
  private final Collection menuContributions = new ArrayList();

  /**
   * The service locator from which services can be retrieved in the future;
   * must not be <code>null</code>.
   */
  private final IWorkbenchWindow window;
 
  /**
   * Help action sets with enable/disable.
   */
  private ICommandListener actionSetListener = new ICommandListener() {
    public void commandChanged(CommandEvent commandEvent) {
      Command cmd = commandEvent.getCommand();
      String commandId = cmd.getId();
      Binding binding = (Binding) commandIdToBinding.get(commandId);
      if (binding != null) {
        if (cmd.isEnabled()) {
          if (!actionSetActiveBindings.contains(binding)) {
            bindingService.addBinding(binding);
            actionSetActiveBindings.add(binding);
          }
        } else if (actionSetActiveBindings.contains(binding)) {
          bindingService.removeBinding(binding);
          actionSetActiveBindings.remove(binding);
        }
      }
    }
  };
 
  /**
   * Map every commandId to its binding.
   */
  private HashMap commandIdToBinding = new HashMap();
 
  /**
   * Which bindings do we currently have outstanding.
   */
  private HashSet actionSetActiveBindings = new HashSet();

  /**
   * Constructs a new instance of {@link LegacyActionPersistence}.
   *
   * @param window
   *            The window from which the services should be retrieved; must
   *            not be <code>null</code>.
   */
  public LegacyActionPersistence(final IWorkbenchWindow window) {
    // TODO Blind casts are bad.
    this.bindingService = (BindingService) window
        .getService(IBindingService.class);

    this.commandService = (ICommandService) window
        .getService(ICommandService.class);
    this.window = window;
  }

  /**
   * Deactivates all of the activations made by this class, and then clears
   * the collection. This should be called before every read.
   */
  private final void clearActivations() {
    final IHandlerService service = (IHandlerService) window
        .getService(IHandlerService.class);
    service.deactivateHandlers(handlerActivations);
    final Iterator activationItr = handlerActivations.iterator();
    while (activationItr.hasNext()) {
      final IHandlerActivation activation = (IHandlerActivation) activationItr
          .next();
      final IHandler handler = activation.getHandler();
      if (handler != null) {
        handler.dispose();
      }
    }
    handlerActivations.clear();
  }

  /**
   * Removes all of the bindings made by this class, and then clears the
   * collection. This should be called before every read.
   */
  private final void clearBindings() {
    Iterator i = commandIdToBinding.entrySet().iterator();
    while (i.hasNext()) {
      Map.Entry entry = (Map.Entry) i.next();
      String commandId = (String) entry.getKey();
      Binding binding = (Binding) entry.getValue();
      commandService.getCommand(commandId).removeCommandListener(actionSetListener);
      if (binding!=null && actionSetActiveBindings.contains(binding)) {
        bindingService.removeBinding(binding);
      }
    }
    commandIdToBinding.clear();
    actionSetActiveBindings.clear();
  }

  /**
   * Removes all of the image bindings made by this class, and then clears the
   * collection. This should be called before every read.
   *
   */
  private final void clearImages() {
    // TODO Implement
  }

  /**
   * Removes all of the contributions made by this class, and then clears the
   * collection. This should be called before every read.
   */
  private final void clearMenus() {
    menuContributions.clear();
  }

  /**
   * Extracts any key bindings from the action. If such a binding exists, it
   * is added to the binding manager.
   *
   * @param element
   *            The action from which the binding should be read; must not be
   *            <code>null</code>.
   * @param command
   *            The fully-parameterized command for which a binding should be
   *            made; must not be <code>null</code>.
   */
  private final void convertActionToBinding(
      final IConfigurationElement element,
      final ParameterizedCommand command, final List warningsToLog) {
    // Figure out which accelerator text to use.
    String acceleratorText = readOptional(element, ATT_ACCELERATOR);
    if (acceleratorText == null) {
      final String label = readOptional(element, ATT_LABEL);
      if (label != null) {
        acceleratorText = LegacyActionTools
            .extractAcceleratorText(label);
      }
    }

    // If there is some accelerator text, generate a key sequence from it.
    if (acceleratorText != null) {
      final IKeyLookup lookup = KeyLookupFactory.getSWTKeyLookup();
      final int acceleratorInt = LegacyActionTools
          .convertAccelerator(acceleratorText);
      final int modifierMask = lookup.getAlt() | lookup.getCommand()
          | lookup.getCtrl() | lookup.getShift();
      final int modifierKeys = acceleratorInt & modifierMask;
      final int naturalKey = acceleratorInt & ~modifierMask;
      final KeyStroke keyStroke = KeyStroke.getInstance(modifierKeys,
          naturalKey);
      final KeySequence keySequence = KeySequence.getInstance(keyStroke);

      final Scheme activeScheme = bindingService.getActiveScheme();

      try {
        final Binding binding = new KeyBinding(keySequence, command,
            activeScheme.getId(), IContextIds.CONTEXT_ID_WINDOW,
            null, null, null, Binding.SYSTEM);
        commandIdToBinding.put(command.getCommand().getId(), binding);

        if (command.getCommand().isEnabled()) {
          bindingService.addBinding(binding);
          actionSetActiveBindings.add(binding);
        }

        command.getCommand().addCommandListener(actionSetListener);
      } catch (IllegalArgumentException e) {
        addWarning(warningsToLog,
            "invalid keybinding: " + e.getMessage(), element, //$NON-NLS-1$
            command.getCommand().getId());
      }
    }
  }

  /**
   * Determine which command to use. This is slightly complicated as actions
   * do not have to have commands, but the new architecture requires it. As
   * such, we will auto-generate a command for the action if the definitionId
   * is missing or points to a command that does not yet exist. All such
   * command identifiers are prefixed with AUTOGENERATED_COMMAND_ID_PREFIX.
   *
   * @param element
   *            The action element from which a command must be generated;
   *            must not be <code>null</code>.
   * @param primaryId
   *            The primary identifier to use when auto-generating a command;
   *            must not be <code>null</code>.
   * @param secondaryId
   *            The secondary identifier to use when auto-generating a
   *            command; must not be <code>null</code>.
   * @param warningsToLog
   *            The collection of warnings logged while reading the extension
   *            point; must not be <code>null</code>.
   * @return the fully-parameterized command; <code>null</code> if an error
   *         occurred.
   */
  private final ParameterizedCommand convertActionToCommand(
      final IConfigurationElement element, final String primaryId,
      final String secondaryId, final List warningsToLog) {
    String commandId = readOptional(element, ATT_DEFINITION_ID);
    Command command = null;
    if (commandId != null) {
      command = commandService.getCommand(commandId);
    }

    final IActionCommandMappingService mappingService = (IActionCommandMappingService) window
        .getService(IActionCommandMappingService.class);
   
    String label = null;
    if ((commandId == null) || (!command.isDefined())) {
      // Add a mapping from this action id to the command id.
      if (commandId == null && mappingService != null) {
        commandId = mappingService.getGeneratedCommandId(primaryId,
            secondaryId);
      }
      if (commandId == null) {
        WorkbenchPlugin.log("MappingService unavailable"); //$NON-NLS-1$
        return null;
      }

      // Read the label attribute.
      label = readRequired(element, ATT_LABEL, warningsToLog,
          "Actions require a non-empty label or definitionId", //$NON-NLS-1$
          commandId);
      if (label == null) {
        label = WorkbenchMessages.LegacyActionPersistence_AutogeneratedCommandName;
      }

      /*
       * Read the tooltip attribute. The tooltip is really the description
       * of the command.
       */
      final String tooltip = readOptional(element, ATT_TOOLTIP);

      // Define the command.
      command = commandService.getCommand(commandId);
      final Category category = commandService.getCategory(null);
      final String name = LegacyActionTools.removeAcceleratorText(Action
          .removeMnemonics(label));
      command.define(name, tooltip, category, null);

      // TODO Decide the command state.
      final String style = readOptional(element, ATT_STYLE);
      if (STYLE_RADIO.equals(style)) {
        final State state = new RadioState();
        // TODO How to set the id?
        final boolean checked = readBoolean(element, ATT_STATE, false);
        state.setValue((checked) ? Boolean.TRUE : Boolean.FALSE);
        command.addState(IMenuStateIds.STYLE, state);

      } else if (STYLE_TOGGLE.equals(style)) {
        final State state = new ToggleState();
        final boolean checked = readBoolean(element, ATT_STATE, false);
        state.setValue((checked) ? Boolean.TRUE : Boolean.FALSE);
        command.addState(IMenuStateIds.STYLE, state);
      }
    }
    // this allows us to look up a "commandId" give the contributionId
    // and the actionId
    if (mappingService != null && commandId != null) {
      mappingService.map(mappingService.getGeneratedCommandId(primaryId,
          secondaryId), commandId);
    }

    return new ParameterizedCommand(command, null);
  }

  /**
   * <p>
   * Extracts the handler information from the given action element. These are
   * registered with the handler service. They are always active.
   * </p>
   *
   * @param element
   *            The action element from which the handler should be read; must
   *            not be <code>null</code>.
   * @param actionId
   *            The identifier of the action for which a handler is being
   *            created; must not be <code>null</code>.
   * @param command
   *            The command for which this handler applies; must not be
   *            <code>null</code>.
   * @param activeWhenExpression
   *            The expression controlling when the handler is active; may be
   *            <code>null</code>.
   * @param viewId
   *            The view to which this handler is associated. This value is
   *            required if this is a view action; otherwise it can be
   *            <code>null</code>.
   * @param warningsToLog
   *            The collection of warnings while parsing this extension point;
   *            must not be <code>null</code>.
   */
  private final void convertActionToHandler(
      final IConfigurationElement element, final String actionId,
      final ParameterizedCommand command,
      final Expression activeWhenExpression, final String viewId,
      final List warningsToLog) {
    // Check to see if this is a retargettable action.
    final boolean retarget = readBoolean(element, ATT_RETARGET, false);

    final boolean classAvailable = (element.getAttribute(ATT_CLASS) != null)
        || (element.getChildren(TAG_CLASS).length != 0);
    // Read the class attribute.
    String classString = readOptional(element, ATT_CLASS);
    if (classAvailable && classString == null) {
      classString = readOptional(element.getChildren(TAG_CLASS)[0],
          ATT_CLASS);
    }

    if (retarget) {
      if (classAvailable && !isPulldown(element)) {
        addWarning(warningsToLog,
            "The class was not null but retarget was set to true", //$NON-NLS-1$
            element, actionId, ATT_CLASS, classString);
      }

      // Add a mapping from this action id to the command id.
      final IActionCommandMappingService mappingService = (IActionCommandMappingService) window
          .getService(IActionCommandMappingService.class);
      if (mappingService != null) {
        mappingService.map(actionId, command.getId());
      } else {
        // this is probably the shutdown case where the service has
        // already disposed.
        addWarning(
            warningsToLog,
            "Retarget service unavailable", //$NON-NLS-1$
            element, actionId);
      }
      return; // This is nothing more to be done.

    } else if (!classAvailable) {
      addWarning(
          warningsToLog,
          "There was no class provided, and the action is not retargettable", //$NON-NLS-1$
          element, actionId);
      return; // There is nothing to be done.
    }

    // Read the enablesFor attribute, and enablement and selection elements.
    SelectionEnabler enabler = null;
    if (element.getAttribute(ATT_ENABLES_FOR) != null) {
      enabler = new SelectionEnabler(element);
    } else {
      IConfigurationElement[] kids = element.getChildren(TAG_ENABLEMENT);
      if (kids.length > 0) {
        enabler = new SelectionEnabler(element);
      }
    }
    final Expression enabledWhenExpression;
    if (enabler == null) {
      enabledWhenExpression = null;
    } else {
      enabledWhenExpression = new LegacySelectionEnablerWrapper(enabler,
          window);
    }

    /*
     * Create the handler. TODO The image style is read at the workbench
     * level, but it is hard to communicate this information to this point.
     * For now, I'll pass null, but this ultimately won't work.
     */
    final ActionDelegateHandlerProxy handler = new ActionDelegateHandlerProxy(
        element, ATT_CLASS, actionId, command, window, null,
        enabledWhenExpression, viewId);

    // Read the help context id.
    final String helpContextId = readOptional(element, ATT_HELP_CONTEXT_ID);
    if (helpContextId != null) {
      commandService.setHelpContextId(handler, helpContextId);
    }

    // Activate the handler.
    final String commandId = command.getId();
    final IHandlerService service = (IHandlerService) window
        .getService(IHandlerService.class);
    final IHandlerActivation handlerActivation;
    if (activeWhenExpression == null) {
      handlerActivation = service.activateHandler(commandId, handler);
    } else {
      handlerActivation = service.activateHandler(commandId, handler,
          activeWhenExpression);
    }
    handlerActivations.add(handlerActivation);
  }



  public final void dispose() {
    super.dispose();
    clear();
  }

  private void clear() {
    clearActivations();
    clearBindings();
    clearImages();
    clearMenus();
  }

  protected final boolean isChangeImportant(final IRegistryChangeEvent event) {
    return !((event.getExtensionDeltas(PlatformUI.PLUGIN_ID,
        IWorkbenchRegistryConstants.PL_ACTION_SETS).length == 0)
        && (event.getExtensionDeltas(PlatformUI.PLUGIN_ID,
            IWorkbenchRegistryConstants.PL_EDITOR_ACTIONS).length == 0)
        && (event.getExtensionDeltas(PlatformUI.PLUGIN_ID,
            IWorkbenchRegistryConstants.PL_POPUP_MENU).length == 0) && (event
        .getExtensionDeltas(PlatformUI.PLUGIN_ID,
            IWorkbenchRegistryConstants.PL_VIEW_ACTIONS).length == 0));
  }

  /**
   * <p>
   * Reads all of the actions from the deprecated extension points. Actions
   * have been replaced with commands, command images, handlers, menu elements
   * and action sets.
   * </p>
   * <p>
   * TODO Before this method is called, all of the extension points must be
   * cleared.
   * </p>
   */
  public final void read() {
    clear();
    LegacyActionPersistence.super.read();

    // Create the extension registry mementos.
    final IExtensionRegistry registry = Platform.getExtensionRegistry();
    int actionSetCount = 0;
    int editorContributionCount = 0;
    int objectContributionCount = 0;
    int viewContributionCount = 0;
    int viewerContributionCount = 0;
    final IConfigurationElement[][] indexedConfigurationElements = new IConfigurationElement[5][];

    // Sort the actionSets extension point.
    final IConfigurationElement[] actionSetsExtensionPoint = registry
        .getConfigurationElementsFor(EXTENSION_ACTION_SETS);
    for (int i = 0; i < actionSetsExtensionPoint.length; i++) {
      final IConfigurationElement element = actionSetsExtensionPoint[i];
      final String name = element.getName();
      if (TAG_ACTION_SET.equals(name)) {
        addElementToIndexedArray(element, indexedConfigurationElements,
            INDEX_ACTION_SETS, actionSetCount++);
      }
    }

    // Sort the editorActions extension point.
    final IConfigurationElement[] editorActionsExtensionPoint = registry
        .getConfigurationElementsFor(EXTENSION_EDITOR_ACTIONS);
    for (int i = 0; i < editorActionsExtensionPoint.length; i++) {
      final IConfigurationElement element = editorActionsExtensionPoint[i];
      final String name = element.getName();
      if (TAG_EDITOR_CONTRIBUTION.equals(name)) {
        addElementToIndexedArray(element, indexedConfigurationElements,
            INDEX_EDITOR_CONTRIBUTIONS, editorContributionCount++);
      }
    }

    // Sort the popupMenus extension point.
    final IConfigurationElement[] popupMenusExtensionPoint = registry
        .getConfigurationElementsFor(EXTENSION_POPUP_MENUS);
    for (int i = 0; i < popupMenusExtensionPoint.length; i++) {
      final IConfigurationElement element = popupMenusExtensionPoint[i];
      final String name = element.getName();
      if (TAG_OBJECT_CONTRIBUTION.equals(name)) {
        addElementToIndexedArray(element, indexedConfigurationElements,
            INDEX_OBJECT_CONTRIBUTIONS, objectContributionCount++);
      } else if (TAG_VIEWER_CONTRIBUTION.equals(name)) {
        addElementToIndexedArray(element, indexedConfigurationElements,
            INDEX_VIEWER_CONTRIBUTIONS, viewerContributionCount++);
      }
    }

    // Sort the viewActions extension point.
    final IConfigurationElement[] viewActionsExtensionPoint = registry
        .getConfigurationElementsFor(EXTENSION_VIEW_ACTIONS);
    for (int i = 0; i < viewActionsExtensionPoint.length; i++) {
      final IConfigurationElement element = viewActionsExtensionPoint[i];
      final String name = element.getName();
      if (TAG_VIEW_CONTRIBUTION.equals(name)) {
        addElementToIndexedArray(element, indexedConfigurationElements,
            INDEX_VIEW_CONTRIBUTIONS, viewContributionCount++);
      }
    }

    readActionSets(indexedConfigurationElements[INDEX_ACTION_SETS],
        actionSetCount);
    readEditorContributions(
        indexedConfigurationElements[INDEX_EDITOR_CONTRIBUTIONS],
        editorContributionCount);
    readObjectContributions(
        indexedConfigurationElements[INDEX_OBJECT_CONTRIBUTIONS],
        objectContributionCount);
    readViewContributions(
        indexedConfigurationElements[INDEX_VIEW_CONTRIBUTIONS],
        viewContributionCount);
    readViewerContributions(
        indexedConfigurationElements[INDEX_VIEWER_CONTRIBUTIONS],
        viewerContributionCount);
   
  }

  /**
   * Reads the actions, and defines all the necessary subcomponents in terms
   * of the command architecture. For each action, there could be a command, a
   * command image binding, a handler and a menu item.
   *
   * @param primaryId
   *            The identifier of the primary object to which this action
   *            belongs. This is used to auto-generate command identifiers
   *            when required. The <code>primaryId</code> must not be
   *            <code>null</code>.
   * @param elements
   *            The action elements to be read; must not be <code>null</code>.
   * @param warningsToLog
   *            The collection of warnings while parsing this extension point;
   *            must not be <code>null</code>.
   * @param visibleWhenExpression
   *            The expression controlling visibility of the corresponding
   *            menu elements; may be <code>null</code>.
   * @param viewId
   *            The view to which this handler is associated. This value is
   *            required if this is a view action; otherwise it can be
   *            <code>null</code>.
   * @return References to the created menu elements; may be <code>null</code>,
   *         and may be empty.
   */
  private final void readActions(final String primaryId,
      final IConfigurationElement[] elements, final List warningsToLog,
      final Expression visibleWhenExpression, final String viewId) {
    for (int i = 0; i < elements.length; i++) {
      final IConfigurationElement element = elements[i];

      /*
       * We might need the identifier to generate the command, so we'll
       * read it out now.
       */
      final String id = readRequired(element, ATT_ID, warningsToLog,
          "Actions require an id"); //$NON-NLS-1$
      if (id == null) {
        continue;
      }

      // Try to break out the command part of the action.
      final ParameterizedCommand command = convertActionToCommand(
          element, primaryId, id, warningsToLog);
      if (command == null) {
        continue;
      }

      convertActionToHandler(element, id, command, visibleWhenExpression,
          viewId, warningsToLog);
      // TODO Read the overrideActionId attribute

      convertActionToBinding(element, command, warningsToLog);

    }
  }

  /**
   * Reads all of the action and menu child elements from the given element.
   *
   * @param element
   *            The configuration element from which the actions and menus
   *            should be read; must not be <code>null</code>, but may be
   *            empty.
   * @param id
   *            The identifier of the contribution being made. This could be
   *            an action set, an editor contribution, a view contribution, a
   *            viewer contribution or an object contribution. This value must
   *            not be <code>null</code>.
   * @param warningsToLog
   *            The list of warnings already logged for this extension point;
   *            must not be <code>null</code>.
   * @param visibleWhenExpression
   *            The expression controlling visibility of the corresponding
   *            menu elements; may be <code>null</code>.
   * @param viewId
   *            The view to which this handler is associated. This value is
   *            required if this is a view action; otherwise it can be
   *            <code>null</code>.
   * @return An array of references to the created menu elements. This value
   *         may be <code>null</code> if there was a problem parsing the
   *         configuration element.
   */
  private final void readActionsAndMenus(
      final IConfigurationElement element, final String id,
      final List warningsToLog,
      final Expression visibleWhenExpression, final String viewId) {

    // Read its child elements.
    final IConfigurationElement[] actionElements = element
        .getChildren(TAG_ACTION);
    readActions(id, actionElements,
        warningsToLog, visibleWhenExpression, viewId);

  }

  /**
   * Reads the deprecated actions from an array of elements from the action
   * sets extension point.
   *
   * @param configurationElements
   *            The configuration elements in the extension point; must not be
   *            <code>null</code>, but may be empty.
   * @param configurationElementCount
   *            The number of configuration elements that are really in the
   *            array.
   */
  private final void readActionSets(
      final IConfigurationElement[] configurationElements,
      final int configurationElementCount) {
    //
    // this was an even dumber fix than modifying the path
    //
    // stupid navigate group
    // SGroup nav = menuService.getGroup(STUPID_NAVIGATE);
    // if (!nav.isDefined()) {
    // nav.define(new SLocation(new SBar(SBar.TYPE_MENU, null)));
    // }
    // stupid navigate group

    final List warningsToLog = new ArrayList(1);

    for (int i = 0; i < configurationElementCount; i++) {
      final IConfigurationElement element = configurationElements[i];

      // Read the action set identifier.
      final String id = readRequired(element, ATT_ID, warningsToLog,
          "Action sets need an id"); //$NON-NLS-1$
      if (id == null) {
        continue;
      }

      // Read the label.
      final String label = readRequired(element, ATT_LABEL,
          warningsToLog, "Actions set need a label", //$NON-NLS-1$
          id);
      if (label == null) {
        continue;
      }

      // Restrict the handler to when the action set is active.
      final LegacyActionSetExpression expression = new LegacyActionSetExpression(
          id, window);


      // Read all of the child elements.
      readActionsAndMenus(element, id,
          warningsToLog, expression, null);
      // Define the action set.
    }

    logWarnings(
        warningsToLog,
        "Warnings while parsing the action sets from the 'org.eclipse.ui.actionSets' extension point"); //$NON-NLS-1$
  }

  /**
   * Reads the deprecated editor contributions from an array of elements from
   * the editor actions extension point.
   *
   * @param configurationElements
   *            The configuration elements in the extension point; must not be
   *            <code>null</code>, but may be empty.
   * @param configurationElementCount
   *            The number of configuration elements that are really in the
   *            array.
   */
  private final void readEditorContributions(
      final IConfigurationElement[] configurationElements,
      final int configurationElementCount) {
    final List warningsToLog = new ArrayList(1);

    for (int i = 0; i < configurationElementCount; i++) {
      final IConfigurationElement element = configurationElements[i];

      // Read the editor contribution identifier.
      final String id = readRequired(element, ATT_ID, warningsToLog,
          "Editor contributions need an id"); //$NON-NLS-1$
      if (id == null) {
        continue;
      }

      /*
       * Read the target id. This is the identifier of the editor with
       * which these contributions are associated.
       */
      final String targetId = readRequired(element, ATT_TARGET_ID,
          warningsToLog, "Editor contributions need a target id", id); //$NON-NLS-1$
      if (targetId == null) {
        continue;
      }
      final Expression visibleWhenExpression = new LegacyEditorContributionExpression(
          targetId, window);

      // Read all of the child elements from the registry.
      readActionsAndMenus(element, id, warningsToLog,
          visibleWhenExpression, null);
    }

    logWarnings(
        warningsToLog,
        "Warnings while parsing the editor contributions from the 'org.eclipse.ui.editorActions' extension point"); //$NON-NLS-1$
  }




  /**
   * Reads the deprecated object contributions from an array of elements from
   * the popup menus extension point.
   *
   * @param configurationElements
   *            The configuration elements in the extension point; must not be
   *            <code>null</code>, but may be empty.
   * @param configurationElementCount
   *            The number of configuration elements that are really in the
   *            array.
   */
  private final void readObjectContributions(
      final IConfigurationElement[] configurationElements,
      final int configurationElementCount) {
    final List warningsToLog = new ArrayList(1);

    for (int i = 0; i < configurationElementCount; i++) {
      final IConfigurationElement element = configurationElements[i];

      // Read the object contribution identifier.
      final String id = readRequired(element, ATT_ID, warningsToLog,
          "Object contributions need an id"); //$NON-NLS-1$
      if (id == null) {
        continue;
      }

      // Read the object class. This influences the visibility.
      final String objectClass = readRequired(element, ATT_OBJECTCLASS,
          warningsToLog,
          "Object contributions need an object class", id); //$NON-NLS-1$
      if (objectClass == null) {
        continue;
      }

      // TODO Read the name filter. This influences the visibility.
      // final String nameFilter = readOptional(element,
      // ATT_NAME_FILTER);

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


      // TODO Read the filter elements.
      // TODO Read the enablement elements.

      // TODO Figure out an appropriate visibility expression.
      // Read the visibility element, if any.
      final Expression visibleWhenExpression = readVisibility(element,
          id, warningsToLog);

      // Read all of the child elements from the registry.
      readActionsAndMenus(element, id, warningsToLog,
          visibleWhenExpression, null);
    }

    logWarnings(
        warningsToLog,
        "Warnings while parsing the object contributions from the 'org.eclipse.ui.popupMenus' extension point"); //$NON-NLS-1$
  }

  /**
   * Reads the deprecated view contributions from an array of elements from
   * the view actions extension point.
   *
   * @param configurationElements
   *            The configuration elements in the extension point; must not be
   *            <code>null</code>, but may be empty.
   * @param configurationElementCount
   *            The number of configuration elements that are really in the
   *            array.
   */
  private final void readViewContributions(
      final IConfigurationElement[] configurationElements,
      final int configurationElementCount) {
    final List warningsToLog = new ArrayList(1);

    for (int i = 0; i < configurationElementCount; i++) {
      final IConfigurationElement element = configurationElements[i];

      // Read the view contribution identifier.
      final String id = readRequired(element, ATT_ID, warningsToLog,
          "View contributions need an id"); //$NON-NLS-1$
      if (id == null) {
        continue;
      }

      /*
       * Read the target id. This is the identifier of the view with which
       * these contributions are associated.
       */
      final String targetId = readRequired(element, ATT_TARGET_ID,
          warningsToLog, "View contributions need a target id", id); //$NON-NLS-1$
      if (targetId == null) {
        continue;
      }
      final Expression visibleWhenExpression = new LegacyViewContributionExpression(
          targetId, window);

      // Read all of the child elements from the registry.
      readActionsAndMenus(element, id, warningsToLog,
          visibleWhenExpression, targetId);
    }

    logWarnings(
        warningsToLog,
        "Warnings while parsing the view contributions from the 'org.eclipse.ui.viewActions' extension point"); //$NON-NLS-1$
  }

  /**
   * Reads the deprecated viewer contributions from an array of elements from
   * the popup menus extension point.
   *
   * @param configurationElements
   *            The configuration elements in the extension point; must not be
   *            <code>null</code>, but may be empty.
   * @param configurationElementCount
   *            The number of configuration elements that are really in the
   *            array.
   */
  private final void readViewerContributions(
      final IConfigurationElement[] configurationElements,
      final int configurationElementCount) {
    final List warningsToLog = new ArrayList(1);

    for (int i = 0; i < configurationElementCount; i++) {
      final IConfigurationElement element = configurationElements[i];

      // Read the viewer contribution identifier.
      final String id = readRequired(element, ATT_ID, warningsToLog,
          "Viewer contributions need an id"); //$NON-NLS-1$
      if (id == null) {
        continue;
      }

      /*
       * Read the target id. This is the identifier of the view with which
       * these contributions are associated.
       */
      final String targetId = readRequired(element, ATT_TARGET_ID,
          warningsToLog, "Viewer contributions need a target id", id); //$NON-NLS-1$
      if (targetId == null) {
        continue;
      }

      // Read the visibility element, if any.
      final Expression visibleWhenExpression = readVisibility(element,
          id, warningsToLog);
      final Expression menuVisibleWhenExpression = new LegacyViewerContributionExpression(
          targetId, window, visibleWhenExpression);

      // Read all of the child elements from the registry.
      readActionsAndMenus(element, id, warningsToLog,
          menuVisibleWhenExpression, targetId);
    }

    logWarnings(
        warningsToLog,
        "Warnings while parsing the viewer contributions from the 'org.eclipse.ui.popupMenus' extension point"); //$NON-NLS-1$
  }
}
TOP

Related Classes of org.eclipse.ui.internal.menus.LegacyActionPersistence

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.