Package org.eclipse.ui.internal.menus

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

/*******************************************************************************
* Copyright (c) 2006, 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.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.expressions.Expression;
import org.eclipse.core.expressions.ExpressionConverter;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.InvalidRegistryObjectException;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarContributionItem;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.actions.CompoundContributionItem;
import org.eclipse.ui.internal.WorkbenchWindow;
import org.eclipse.ui.internal.provisional.presentations.IActionBarPresentationFactory;
import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
import org.eclipse.ui.internal.util.Util;
import org.eclipse.ui.menus.AbstractContributionFactory;
import org.eclipse.ui.menus.CommandContributionItem;
import org.eclipse.ui.menus.IContributionRoot;
import org.eclipse.ui.menus.IMenuService;
import org.eclipse.ui.menus.WorkbenchWindowControlContribution;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.services.IServiceLocator;

/**
* @since 3.3
*
*/
public class MenuAdditionCacheEntry extends AbstractContributionFactory {
  private IConfigurationElement additionElement;

  // Caches

  /**
   * Maps an IContributionItem to its corresponding IConfigurationElement
   */
  Map iciToConfigElementMap = new HashMap();

  /**
   * If an {@link IConfigurationElement} is in the Set then we have already
   * tried (and failed) to load the associated ExecutableExtension.
   *
   * This is used to prevent multiple retries which would spam the Log.
   */
  Set failedLoads = new HashSet();

  /**
   * Maps an IConfigurationElement to its parsed Expression
   */
  private HashMap visWhenMap = new HashMap();

  /**
   * The menu service on which to generate all subcaches.
   */
  private IMenuService menuService;

  public MenuAdditionCacheEntry(IMenuService menuService,
      IConfigurationElement element, String location, String namespace) {
    super(location, namespace);
    this.menuService = menuService;
    this.additionElement = element;
    generateSubCaches();
  }

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

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

        // -ALL- contibuted menus must have an id so create one
        // if necessary
        MenuAdditionCacheEntry subMenuEntry = new MenuAdditionCacheEntry(
            menuService, items[i], location, getNamespace());
        menuService.addContributionFactory(subMenuEntry);
      }
    }
  }

  private Expression getVisibleWhenForItem(IContributionItem item) {
    IConfigurationElement configElement = (IConfigurationElement) iciToConfigElementMap
        .get(item);
    if (configElement == null)
      return null;

    if (!visWhenMap.containsKey(configElement)) {
      // Not parsed yet
      try {
        IConfigurationElement[] visibleConfig = configElement
            .getChildren(IWorkbenchRegistryConstants.TAG_VISIBLE_WHEN);
        if (visibleConfig.length > 0 && visibleConfig.length < 2) {
          IConfigurationElement[] visibleChild = visibleConfig[0]
              .getChildren();
          if (visibleChild.length > 0) {
            Expression visWhen = ExpressionConverter.getDefault()
                .perform(visibleChild[0]);
            visWhenMap.put(configElement, visWhen);
          }
        }
      } catch (InvalidRegistryObjectException e) {
        visWhenMap.put(configElement, null);
        // TODO Auto-generated catch block
        e.printStackTrace();
      } catch (CoreException e) {
        visWhenMap.put(configElement, null);
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }

    return (Expression) visWhenMap.get(configElement);
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.ui.internal.menus.AbstractContributionFactory#createContributionItems(org.eclipse.ui.internal.menus.IMenuService,
   *      java.util.List)
   */
  public void createContributionItems(IServiceLocator serviceLocator,
      IContributionRoot additions) {
    IActionBarPresentationFactory actionBarPresentationFactory = null;

    WorkbenchWindow window = (WorkbenchWindow) serviceLocator
        .getService(IWorkbenchWindow.class);
    if (window != null) {
      actionBarPresentationFactory = window
          .getActionBarPresentationFactory();
    }

    IConfigurationElement[] items = additionElement.getChildren();
    for (int i = 0; i < items.length; i++) {
      String itemType = items[i].getName();
      IContributionItem newItem = null;

      if (IWorkbenchRegistryConstants.TAG_COMMAND.equals(itemType)) {
        newItem = createCommandAdditionContribution(serviceLocator,
            items[i]);
      } else if (IWorkbenchRegistryConstants.TAG_DYNAMIC.equals(itemType)) {
        newItem = createDynamicAdditionContribution(items[i]);
      } else if (IWorkbenchRegistryConstants.TAG_CONTROL.equals(itemType)) {
        newItem = createControlAdditionContribution(items[i]);
      } else if (IWorkbenchRegistryConstants.TAG_SEPARATOR
          .equals(itemType)) {
        newItem = createSeparatorAdditionContribution(items[i]);
      } else if (IWorkbenchRegistryConstants.TAG_MENU.equals(itemType)) {
        newItem = createMenuAdditionContribution(items[i]);
      } else if (IWorkbenchRegistryConstants.TAG_TOOLBAR.equals(itemType)) {
        newItem = createToolBarAdditionContribution(
            actionBarPresentationFactory, items[i]);
      }

      // Cache the relationship between the ICI and the
      // registry element used to back it
      if (newItem != null) {
        iciToConfigElementMap.put(newItem, items[i]);
        additions.addContributionItem(newItem,
            getVisibleWhenForItem(newItem));
      }
    }
  }

  /**
   * @param configurationElement
   * @return
   */
  private IContributionItem createToolBarAdditionContribution(
      IActionBarPresentationFactory actionBarPresentationFactory,
      IConfigurationElement configurationElement) {
    if (!getLocation().startsWith("toolbar")) { //$NON-NLS-1$
      return null;
    }
    if (actionBarPresentationFactory != null) {
      return actionBarPresentationFactory.createToolBarContributionItem(
          actionBarPresentationFactory.createToolBarManager(),
          getId(configurationElement));
    }
    return new ToolBarContributionItem(new ToolBarManager(),
        getId(configurationElement));
  }

  /**
   * @param configurationElement
   * @return the menu manager
   */
  private IContributionItem createMenuAdditionContribution(
      final IConfigurationElement menuAddition) {
    // Is this for a menu or a ToolBar ? We can't create
    // a menu directly under a Toolbar; we have to add an
    // item of style 'pulldown'
    if (getLocation().startsWith("toolbar")) { //$NON-NLS-1$
      return null;
    }

    String text = getLabel(menuAddition);
    String mnemonic = getMnemonic(menuAddition);
    if (text != null && mnemonic != null) {
      int idx = text.indexOf(mnemonic);
      if (idx != -1) {
        text = text.substring(0, idx) + '&' + text.substring(idx);
      }
    }
    return new MenuManager(text, getId(menuAddition));
  }

  /**
   * @param configurationElement
   * @return
   */
  private IContributionItem createSeparatorAdditionContribution(
      final IConfigurationElement sepAddition) {
    if (isSeparatorVisible(sepAddition)) {
      return new Separator(getName(sepAddition));
    }
    return new GroupMarker(getName(sepAddition));
  }

  /**
   * @return
   */
  private IContributionItem createDynamicAdditionContribution(
      final IConfigurationElement dynamicAddition) {
    // If we've already tried (and failed) to load the
    // executable extension then skip this addition.
    if (failedLoads.contains(dynamicAddition))
      return null;

    // Attempt to load the addition's EE (creates a new instance)
    final CompoundContributionItem loadedDynamicContribution = (CompoundContributionItem) Util
        .safeLoadExecutableExtension(dynamicAddition,
            IWorkbenchRegistryConstants.ATT_CLASS,
            CompoundContributionItem.class);

    // Cache failures
    if (loadedDynamicContribution == null) {
      failedLoads.add(loadedDynamicContribution);
      return null;
    }

    // TODO provide a proxy IContributionItem that defers instantiation
    // adding contribution items in a menu instantiates this object ...
    // we need to defer loading until fill(*) is called.
    return loadedDynamicContribution;
  }

  /**
   * @return
   */
  private IContributionItem createControlAdditionContribution(
      final IConfigurationElement widgetAddition) {
    if (!getLocation().startsWith("toolbar")) { //$NON-NLS-1$
      return null;
    }
    // If we've already tried (and failed) to load the
    // executable extension then skip this addirion.
    if (failedLoads.contains(widgetAddition))
      return null;

    // Attempt to load the addition's EE (creates a new instance)
    final WorkbenchWindowControlContribution loadedWidget = (WorkbenchWindowControlContribution) Util
        .safeLoadExecutableExtension(widgetAddition,
            IWorkbenchRegistryConstants.ATT_CLASS,
            WorkbenchWindowControlContribution.class);

    // Cache failures
    if (loadedWidget == null) {
      failedLoads.add(widgetAddition);
      return null;
    }

    // explicitly set the id
    ((InternalControlContribution) loadedWidget)
        .setId(getId(widgetAddition));

    return loadedWidget;
  }

  /**
   * @param configurationElement
   * @return
   */
  private IContributionItem createCommandAdditionContribution(
      IServiceLocator locator, final IConfigurationElement commandAddition) {
    return new CommandContributionItem(locator, getId(commandAddition),
        getCommandId(commandAddition), getParameters(commandAddition),
        getIconDescriptor(commandAddition),
        getDisabledIconDescriptor(commandAddition),
        getHoverIconDescriptor(commandAddition),
        getLabel(commandAddition), getMnemonic(commandAddition),
        getTooltip(commandAddition), getStyle(commandAddition));
  }

  /*
   * Support Utilities
   */
  public static String getId(IConfigurationElement element) {
    String id = element.getAttribute(IWorkbenchRegistryConstants.ATT_ID);

    // For sub-menu management -all- items must be id'd so enforce this
    // here (we could optimize by checking the 'name' of the config
    // element == "menu"
    if (id == null || id.length() == 0)
      id = element.toString();

    return id;
  }

  static String getName(IConfigurationElement element) {
    return element.getAttribute(IWorkbenchRegistryConstants.ATT_NAME);
  }

  static String getLabel(IConfigurationElement element) {
    return element.getAttribute(IWorkbenchRegistryConstants.ATT_LABEL);
  }

  static String getMnemonic(IConfigurationElement element) {
    return element.getAttribute(IWorkbenchRegistryConstants.ATT_MNEMONIC);
  }

  static String getTooltip(IConfigurationElement element) {
    return element.getAttribute(IWorkbenchRegistryConstants.ATT_TOOLTIP);
  }

  static String getIconPath(IConfigurationElement element) {
    return element.getAttribute(IWorkbenchRegistryConstants.ATT_ICON);
  }

  static String getDisabledIconPath(IConfigurationElement element) {
    return element
        .getAttribute(IWorkbenchRegistryConstants.ATT_DISABLEDICON);
  }

  static String getHoverIconPath(IConfigurationElement element) {
    return element.getAttribute(IWorkbenchRegistryConstants.ATT_HOVERICON);
  }

  static ImageDescriptor getIconDescriptor(IConfigurationElement element) {
    String extendingPluginId = element.getDeclaringExtension()
        .getContributor().getName();

    String iconPath = getIconPath(element);
    if (iconPath != null) {
      return AbstractUIPlugin.imageDescriptorFromPlugin(
          extendingPluginId, iconPath);
    }
    return null;
  }

  static ImageDescriptor getDisabledIconDescriptor(
      IConfigurationElement element) {
    String extendingPluginId = element.getDeclaringExtension()
        .getContributor().getName();

    String iconPath = getDisabledIconPath(element);
    if (iconPath != null) {
      return AbstractUIPlugin.imageDescriptorFromPlugin(
          extendingPluginId, iconPath);
    }
    return null;
  }

  static ImageDescriptor getHoverIconDescriptor(IConfigurationElement element) {
    String extendingPluginId = element.getDeclaringExtension()
        .getContributor().getName();

    String iconPath = getHoverIconPath(element);
    if (iconPath != null) {
      return AbstractUIPlugin.imageDescriptorFromPlugin(
          extendingPluginId, iconPath);
    }
    return null;
  }

  public static boolean isSeparatorVisible(IConfigurationElement element) {
    String val = element
        .getAttribute(IWorkbenchRegistryConstants.ATT_VISIBLE);
    return Boolean.valueOf(val).booleanValue();
  }

  public static String getClassSpec(IConfigurationElement element) {
    return element.getAttribute(IWorkbenchRegistryConstants.ATT_CLASS);
  }

  public static String getCommandId(IConfigurationElement element) {
    return element.getAttribute(IWorkbenchRegistryConstants.ATT_COMMAND_ID);
  }

  private int getStyle(IConfigurationElement element) {
    String style = element
        .getAttribute(IWorkbenchRegistryConstants.ATT_STYLE);
    if (style == null || style.length() == 0) {
      return CommandContributionItem.STYLE_PUSH;
    }
    if (IWorkbenchRegistryConstants.STYLE_TOGGLE.equals(style)) {
      return CommandContributionItem.STYLE_CHECK;
    }
    if (IWorkbenchRegistryConstants.STYLE_RADIO.equals(style)) {
      return CommandContributionItem.STYLE_RADIO;
    }
    if (IWorkbenchRegistryConstants.STYLE_PULLDOWN.equals(style)) {
      return CommandContributionItem.STYLE_PULLDOWN;
    }
    return CommandContributionItem.STYLE_PUSH;
  }

  /**
   * @param element
   * @return A map of parameters names to parameter values. All Strings. The
   *         map may be empty.
   */
  public static Map getParameters(IConfigurationElement element) {
    HashMap map = new HashMap();
    IConfigurationElement[] parameters = element
        .getChildren(IWorkbenchRegistryConstants.TAG_PARAMETER);
    for (int i = 0; i < parameters.length; i++) {
      String name = parameters[i]
          .getAttribute(IWorkbenchRegistryConstants.ATT_NAME);
      String value = parameters[i]
          .getAttribute(IWorkbenchRegistryConstants.ATT_VALUE);
      if (name != null && value != null) {
        map.put(name, value);
      }
    }
    return map;
  }
}
TOP

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

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.