blob: 9152f6f687a5e9ea68517b42b7929710b0ccb4bf [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2008 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.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionDelta;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IRegistryChangeEvent;
import org.eclipse.core.runtime.Platform;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
import org.eclipse.ui.internal.services.RegistryPersistence;
import org.eclipse.ui.menus.AbstractContributionFactory;
/**
* <p>
* A static class for accessing the registry.
* </p>
* <p>
* This class is not intended for use outside of the
* <code>org.eclipse.ui.workbench</code> plug-in.
* </p>
*
* @since 3.2
*/
final class MenuPersistence extends RegistryPersistence {
private final WorkbenchMenuService menuService;
/**
* Constructs a new instance of {@link MenuPersistence}.
*
* @param workbenchMenuService
*
* @param workbenchMenuService
* The menu service which should be populated with the values
* from the registry; must not be <code>null</code>.
*/
MenuPersistence(final WorkbenchMenuService workbenchMenuService) {
if (workbenchMenuService == null) {
throw new NullPointerException("The menu service cannot be null"); //$NON-NLS-1$
}
this.menuService = workbenchMenuService;
}
public final void dispose() {
super.dispose();
}
protected final boolean isChangeImportant(final IRegistryChangeEvent event) {
/*
* TODO Menus will need to be re-read (i.e., re-verified) if any of the
* menu extensions change (i.e., menus), or if any of the command
* extensions change (i.e., action definitions).
*/
return false;
}
public boolean menusNeedUpdating(final IRegistryChangeEvent event) {
final IExtensionDelta[] menuDeltas = event.getExtensionDeltas(
PlatformUI.PLUGIN_ID, IWorkbenchRegistryConstants.PL_MENUS);
if (menuDeltas.length == 0) {
return false;
}
return true;
}
/**
* <p>
* Reads all of the menu elements and action sets from the registry.
* </p>
* <p>
* TODO Add support for modifications.
* </p>
*/
protected final void read() {
super.read();
// Read legacy 3.2 'trim' additions
readTrimAdditions();
// read the 3.3 menu additions
readAdditions();
}
//
// 3.3 menu extension code
//
public void readTrimAdditions() {
if (menuService == null)
return;
final IExtensionRegistry registry = Platform.getExtensionRegistry();
final IConfigurationElement[] configElements = registry
.getConfigurationElementsFor(EXTENSION_MENUS);
// Create a cache entry for every menu addition
for (int i = 0; i < configElements.length; i++) {
// Only process 'group' entries
if (!TAG_GROUP.equals(configElements[i].getName()))
continue;
String id = configElements[i]
.getAttribute(IWorkbenchRegistryConstants.ATT_ID);
// Define the initial URI spec
String uriSpec = "toolbar:" + id; //$NON-NLS-1$
if (configElements[i].getChildren(TAG_LOCATION).length > 0) {
IConfigurationElement location = configElements[i]
.getChildren(TAG_LOCATION)[0];
if (location.getChildren(TAG_ORDER).length > 0) {
IConfigurationElement order = location
.getChildren(TAG_ORDER)[0];
String pos = order
.getAttribute(IWorkbenchRegistryConstants.ATT_POSITION);
String relTo = order
.getAttribute(IWorkbenchRegistryConstants.ATT_RELATIVE_TO);
uriSpec += "?" + pos + "=" + relTo; //$NON-NLS-1$ //$NON-NLS-2$
// HACK! We expect that the new trim group is -always-
// relative to
// one of the 'default' groups; indicating which trim area
// they're in
MenuLocationURI uri = new MenuLocationURI(
"toolbar:" + relTo); //$NON-NLS-1$
List trimAdditions = menuService.getAdditionsForURI(uri);
//
// TODO convert the TrimAdditionCacheEntry over to use the
// new MenuCacheEntry and addCacheForURI(*)
// OK, add the addition to this area
uri = new MenuLocationURI(uriSpec);
trimAdditions.add(new TrimAdditionCacheEntry(
configElements[i], uri, menuService));
} else {
// Must be a default group; make a new entry cache
MenuLocationURI uri = new MenuLocationURI(uriSpec);
// NOTE: 'getAdditionsForURI' forces creation
menuService.getAdditionsForURI(uri);
}
}
}
}
public void readAdditions() {
final IExtensionRegistry registry = Platform.getExtensionRegistry();
ArrayList configElements = new ArrayList();
final IConfigurationElement[] menusExtensionPoint = registry
.getConfigurationElementsFor(EXTENSION_MENUS);
// Create a cache entry for every menu addition;
for (int i = 0; i < menusExtensionPoint.length; i++) {
if (PL_MENU_CONTRIBUTION.equals(menusExtensionPoint[i].getName())) {
configElements.add(menusExtensionPoint[i]);
}
}
Comparator comparer = new Comparator() {
public int compare(Object o1, Object o2) {
IConfigurationElement c1 = (IConfigurationElement) o1;
IConfigurationElement c2 = (IConfigurationElement) o2;
return c1.getNamespaceIdentifier().compareToIgnoreCase(
c2.getNamespaceIdentifier());
}
};
Collections.sort(configElements, comparer);
Iterator i = configElements.iterator();
while (i.hasNext()) {
final IConfigurationElement configElement = (IConfigurationElement) i
.next();
AbstractContributionFactory newFactory = null;
if (isProgramaticContribution(configElement))
newFactory = new ProxyMenuAdditionCacheEntry(
configElement
.getAttribute(IWorkbenchRegistryConstants.TAG_LOCATION_URI),
configElement.getNamespaceIdentifier(), configElement);
else
newFactory = new MenuAdditionCacheEntry(
menuService,
configElement,
configElement
.getAttribute(IWorkbenchRegistryConstants.TAG_LOCATION_URI),
configElement.getNamespaceIdentifier());
if (newFactory != null)
menuService.addContributionFactory(newFactory);
}
}
/**
* Return whether or not this contribution is programmatic (ie: has a class attribute).
*
* @param menuAddition
* @return whether or not this contribution is programamtic
* @since 3.5
*/
private boolean isProgramaticContribution(IConfigurationElement menuAddition) {
return menuAddition.getAttribute(IWorkbenchRegistryConstants.ATT_CLASS) != null;
}
}