| /******************************************************************************* |
| * 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.handlers; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.core.commands.IHandler; |
| import org.eclipse.core.expressions.Expression; |
| 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.handlers.IHandlerActivation; |
| import org.eclipse.ui.handlers.IHandlerService; |
| import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; |
| import org.eclipse.ui.internal.services.RegistryPersistence; |
| import org.eclipse.ui.services.IEvaluationService; |
| |
| /** |
| * <p> |
| * A static class for accessing the registry. |
| * </p> |
| * |
| * @since 3.1 |
| */ |
| public final class HandlerPersistence extends RegistryPersistence { |
| |
| /** |
| * The index of the command elements in the indexed array. |
| * |
| * @see HandlerPersistence#read() |
| */ |
| private static final int INDEX_COMMAND_DEFINITIONS = 0; |
| |
| /** |
| * The index of the command elements in the indexed array. |
| * |
| * @see HandlerPersistence#read() |
| */ |
| private static final int INDEX_HANDLER_DEFINITIONS = 1; |
| |
| /** |
| * The index of the handler submissions in the indexed array. |
| * |
| * @see HandlerPersistence#read() |
| */ |
| private static final int INDEX_HANDLER_SUBMISSIONS = 2; |
| |
| /** |
| * 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 handler service with which this persistence class is associated. This |
| * value must not be <code>null</code>. |
| */ |
| private final IHandlerService handlerService; |
| |
| private IEvaluationService evaluationService; |
| |
| /** |
| * Constructs a new instance of <code>HandlerPersistence</code>. |
| * |
| * @param handlerService |
| * The handler service with which the handlers should be |
| * registered; must not be <code>null</code>. |
| * @param evaluationService |
| * The evaluation service used by handler proxies with enabled |
| * when expressions |
| */ |
| HandlerPersistence(final IHandlerService handlerService, |
| IEvaluationService evaluationService) { |
| this.handlerService = handlerService; |
| this.evaluationService = evaluationService; |
| } |
| |
| /** |
| * Deactivates all of the activations made by this class, and then clears |
| * the collection. This should be called before every read. |
| * |
| * @param handlerService |
| * The service handling the activations; must not be |
| * <code>null</code>. |
| */ |
| private final void clearActivations(final IHandlerService handlerService) { |
| handlerService.deactivateHandlers(handlerActivations); |
| Iterator i = handlerActivations.iterator(); |
| while (i.hasNext()) { |
| IHandlerActivation activation = (IHandlerActivation) i.next(); |
| if (activation.getHandler()!=null) { |
| activation.getHandler().dispose(); |
| } |
| } |
| handlerActivations.clear(); |
| } |
| |
| public final void dispose() { |
| super.dispose(); |
| clearActivations(handlerService); |
| } |
| |
| protected final boolean isChangeImportant(final IRegistryChangeEvent event) { |
| return false; |
| } |
| |
| public boolean handlersNeedUpdating(final IRegistryChangeEvent event) { |
| /* |
| * Handlers will need to be re-read (i.e., re-verified) if any of the |
| * handler extensions change (i.e., handlers, commands), or if any of |
| * the command extensions change (i.e., action definitions). |
| */ |
| final IExtensionDelta[] handlerDeltas = event.getExtensionDeltas( |
| PlatformUI.PLUGIN_ID, IWorkbenchRegistryConstants.PL_HANDLERS); |
| if (handlerDeltas.length == 0) { |
| final IExtensionDelta[] commandDeltas = event.getExtensionDeltas( |
| PlatformUI.PLUGIN_ID, |
| IWorkbenchRegistryConstants.PL_COMMANDS); |
| if (commandDeltas.length == 0) { |
| final IExtensionDelta[] actionDefinitionDeltas = event |
| .getExtensionDeltas( |
| PlatformUI.PLUGIN_ID, |
| IWorkbenchRegistryConstants.PL_ACTION_DEFINITIONS); |
| if (actionDefinitionDeltas.length == 0) { |
| return false; |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| /** |
| * Reads all of the handlers from the registry |
| * |
| * @param handlerService |
| * The handler service which should be populated with the values |
| * from the registry; must not be <code>null</code>. |
| */ |
| protected final void read() { |
| super.read(); |
| reRead(); |
| } |
| |
| public final void reRead() { |
| // Create the extension registry mementos. |
| final IExtensionRegistry registry = Platform.getExtensionRegistry(); |
| int commandDefinitionCount = 0; |
| int handlerDefinitionCount = 0; |
| int handlerSubmissionCount = 0; |
| final IConfigurationElement[][] indexedConfigurationElements = new IConfigurationElement[3][]; |
| |
| // Sort the commands extension point based on element name. |
| final IConfigurationElement[] commandsExtensionPoint = registry |
| .getConfigurationElementsFor(EXTENSION_COMMANDS); |
| for (int i = 0; i < commandsExtensionPoint.length; i++) { |
| final IConfigurationElement configurationElement = commandsExtensionPoint[i]; |
| final String name = configurationElement.getName(); |
| |
| // Check if it is a handler submission or a command definition. |
| if (TAG_HANDLER_SUBMISSION.equals(name)) { |
| addElementToIndexedArray(configurationElement, |
| indexedConfigurationElements, |
| INDEX_HANDLER_SUBMISSIONS, handlerSubmissionCount++); |
| } else if (TAG_COMMAND.equals(name)) { |
| addElementToIndexedArray(configurationElement, |
| indexedConfigurationElements, |
| INDEX_COMMAND_DEFINITIONS, commandDefinitionCount++); |
| } |
| } |
| |
| // Sort the handler extension point based on element name. |
| final IConfigurationElement[] handlersExtensionPoint = registry |
| .getConfigurationElementsFor(EXTENSION_HANDLERS); |
| for (int i = 0; i < handlersExtensionPoint.length; i++) { |
| final IConfigurationElement configurationElement = handlersExtensionPoint[i]; |
| final String name = configurationElement.getName(); |
| |
| // Check if it is a handler submission or a command definition. |
| if (TAG_HANDLER.equals(name)) { |
| addElementToIndexedArray(configurationElement, |
| indexedConfigurationElements, |
| INDEX_HANDLER_DEFINITIONS, handlerDefinitionCount++); |
| } |
| } |
| |
| clearActivations(handlerService); |
| readDefaultHandlersFromRegistry( |
| indexedConfigurationElements[INDEX_COMMAND_DEFINITIONS], |
| commandDefinitionCount); |
| readHandlerSubmissionsFromRegistry( |
| indexedConfigurationElements[INDEX_HANDLER_SUBMISSIONS], |
| handlerSubmissionCount); |
| readHandlersFromRegistry( |
| indexedConfigurationElements[INDEX_HANDLER_DEFINITIONS], |
| handlerDefinitionCount); |
| } |
| |
| /** |
| * Reads the default handlers from an array of command elements from the |
| * commands extension point. |
| * |
| * @param configurationElements |
| * The configuration elements in the commands 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 readDefaultHandlersFromRegistry( |
| final IConfigurationElement[] configurationElements, |
| final int configurationElementCount) { |
| for (int i = 0; i < configurationElementCount; i++) { |
| final IConfigurationElement configurationElement = configurationElements[i]; |
| |
| /* |
| * Read out the command identifier. This was already checked by |
| * <code>CommandPersistence</code>, so we'll just ignore any |
| * problems here. |
| */ |
| final String commandId = readOptional(configurationElement, ATT_ID); |
| if (commandId == null) { |
| continue; |
| } |
| |
| // Check to see if we have a default handler of any kind. |
| if ((configurationElement.getAttribute(ATT_DEFAULT_HANDLER) == null) |
| && (configurationElement.getChildren(TAG_DEFAULT_HANDLER).length == 0)) { |
| continue; |
| } |
| |
| handlerActivations.add(handlerService |
| .activateHandler(commandId, new HandlerProxy(commandId, |
| configurationElement, ATT_DEFAULT_HANDLER))); |
| } |
| } |
| |
| /** |
| * Reads all of the handlers from the handlers extension point. |
| * |
| * @param configurationElements |
| * The configuration elements in the commands 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. |
| * @param handlerService |
| * The handler service to which the handlers should be added; |
| * must not be <code>null</code>. |
| */ |
| private final void readHandlersFromRegistry( |
| final IConfigurationElement[] configurationElements, |
| final int configurationElementCount) { |
| final List warningsToLog = new ArrayList(1); |
| |
| for (int i = 0; i < configurationElementCount; i++) { |
| final IConfigurationElement configurationElement = configurationElements[i]; |
| |
| // Read out the command identifier. |
| final String commandId = readRequired(configurationElement, |
| ATT_COMMAND_ID, warningsToLog, "Handlers need a command id"); //$NON-NLS-1$ |
| if (commandId == null) { |
| continue; |
| } |
| |
| // Check to see if we have a handler class. |
| if (!checkClass(configurationElement, warningsToLog, |
| "Handlers need a class", commandId)) { //$NON-NLS-1$ |
| continue; |
| } |
| |
| // Get the activeWhen and enabledWhen expressions. |
| final Expression activeWhenExpression = readWhenElement( |
| configurationElement, TAG_ACTIVE_WHEN, commandId, |
| warningsToLog); |
| if (activeWhenExpression == ERROR_EXPRESSION) { |
| continue; |
| } |
| final Expression enabledWhenExpression = readWhenElement( |
| configurationElement, TAG_ENABLED_WHEN, commandId, |
| warningsToLog); |
| if (enabledWhenExpression == ERROR_EXPRESSION) { |
| continue; |
| } |
| |
| final IHandler proxy = new HandlerProxy(commandId, configurationElement, |
| ATT_CLASS, enabledWhenExpression, evaluationService); |
| handlerActivations.add(handlerService.activateHandler(commandId, |
| proxy, activeWhenExpression)); |
| |
| // Read out the help context identifier. |
| final String helpContextId = readOptional(configurationElement, |
| ATT_HELP_CONTEXT_ID); |
| handlerService.setHelpContextId(proxy, helpContextId); |
| } |
| |
| logWarnings( |
| warningsToLog, |
| "Warnings while parsing the handlers from the 'org.eclipse.ui.handlers' extension point."); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Reads all of the handler submissions from the commands extension point. |
| * |
| * @param configurationElements |
| * The configuration elements in the commands 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. |
| * @param handlerService |
| * The handler service to which the handlers should be added; |
| * must not be <code>null</code>. |
| */ |
| private final void readHandlerSubmissionsFromRegistry( |
| final IConfigurationElement[] configurationElements, |
| final int configurationElementCount) { |
| final List warningsToLog = new ArrayList(1); |
| |
| for (int i = 0; i < configurationElementCount; i++) { |
| final IConfigurationElement configurationElement = configurationElements[i]; |
| |
| // Read out the command identifier. |
| final String commandId = readRequired(configurationElement, |
| ATT_COMMAND_ID, warningsToLog, |
| "Handler submissions need a command id"); //$NON-NLS-1$ |
| if (commandId == null) { |
| continue; |
| } |
| |
| handlerActivations.add(handlerService.activateHandler(commandId, |
| new LegacyHandlerWrapper(new LegacyHandlerProxy( |
| configurationElement)))); |
| } |
| |
| logWarnings( |
| warningsToLog, |
| "Warnings while parsing the handler submissions from the 'org.eclipse.ui.commands' extension point."); //$NON-NLS-1$ |
| } |
| } |