001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.handlers;
011:
012: import java.util.ArrayList;
013: import java.util.Collection;
014: import java.util.List;
015:
016: import org.eclipse.core.commands.IHandler;
017: import org.eclipse.core.expressions.Expression;
018: import org.eclipse.core.runtime.IConfigurationElement;
019: import org.eclipse.core.runtime.IExtensionDelta;
020: import org.eclipse.core.runtime.IExtensionRegistry;
021: import org.eclipse.core.runtime.IRegistryChangeEvent;
022: import org.eclipse.core.runtime.Platform;
023: import org.eclipse.ui.PlatformUI;
024: import org.eclipse.ui.handlers.IHandlerService;
025: import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
026: import org.eclipse.ui.internal.services.IEvaluationService;
027: import org.eclipse.ui.internal.services.RegistryPersistence;
028:
029: /**
030: * <p>
031: * A static class for accessing the registry.
032: * </p>
033: *
034: * @since 3.1
035: */
036: final class HandlerPersistence extends RegistryPersistence {
037:
038: /**
039: * The index of the command elements in the indexed array.
040: *
041: * @see HandlerPersistence#read()
042: */
043: private static final int INDEX_COMMAND_DEFINITIONS = 0;
044:
045: /**
046: * The index of the command elements in the indexed array.
047: *
048: * @see HandlerPersistence#read()
049: */
050: private static final int INDEX_HANDLER_DEFINITIONS = 1;
051:
052: /**
053: * The index of the handler submissions in the indexed array.
054: *
055: * @see HandlerPersistence#read()
056: */
057: private static final int INDEX_HANDLER_SUBMISSIONS = 2;
058:
059: /**
060: * The handler activations that have come from the registry. This is used to
061: * flush the activations when the registry is re-read. This value is never
062: * <code>null</code>
063: */
064: private final Collection handlerActivations = new ArrayList();
065:
066: /**
067: * The handler service with which this persistence class is associated. This
068: * value must not be <code>null</code>.
069: */
070: private final IHandlerService handlerService;
071:
072: private IEvaluationService evaluationService;
073:
074: /**
075: * Constructs a new instance of <code>HandlerPersistence</code>.
076: *
077: * @param handlerService
078: * The handler service with which the handlers should be
079: * registered; must not be <code>null</code>.
080: * @param evaluationService
081: * The evaluation service used by handler proxies with enabled
082: * when expressions
083: */
084: HandlerPersistence(final IHandlerService handlerService,
085: IEvaluationService evaluationService) {
086: this .handlerService = handlerService;
087: this .evaluationService = evaluationService;
088: }
089:
090: /**
091: * Deactivates all of the activations made by this class, and then clears
092: * the collection. This should be called before every read.
093: *
094: * @param handlerService
095: * The service handling the activations; must not be
096: * <code>null</code>.
097: */
098: private final void clearActivations(
099: final IHandlerService handlerService) {
100: handlerService.deactivateHandlers(handlerActivations);
101: handlerActivations.clear();
102: }
103:
104: public final void dispose() {
105: super .dispose();
106: clearActivations(handlerService);
107: }
108:
109: protected final boolean isChangeImportant(
110: final IRegistryChangeEvent event) {
111: /*
112: * Handlers will need to be re-read (i.e., re-verified) if any of the
113: * handler extensions change (i.e., handlers, commands), or if any of
114: * the command extensions change (i.e., action definitions).
115: */
116: final IExtensionDelta[] handlerDeltas = event
117: .getExtensionDeltas(PlatformUI.PLUGIN_ID,
118: IWorkbenchRegistryConstants.PL_HANDLERS);
119: if (handlerDeltas.length == 0) {
120: final IExtensionDelta[] commandDeltas = event
121: .getExtensionDeltas(PlatformUI.PLUGIN_ID,
122: IWorkbenchRegistryConstants.PL_COMMANDS);
123: if (commandDeltas.length == 0) {
124: final IExtensionDelta[] actionDefinitionDeltas = event
125: .getExtensionDeltas(
126: PlatformUI.PLUGIN_ID,
127: IWorkbenchRegistryConstants.PL_ACTION_DEFINITIONS);
128: if (actionDefinitionDeltas.length == 0) {
129: return false;
130: }
131: }
132: }
133:
134: return true;
135: }
136:
137: /**
138: * Reads all of the handlers from the registry
139: *
140: * @param handlerService
141: * The handler service which should be populated with the values
142: * from the registry; must not be <code>null</code>.
143: */
144: protected final void read() {
145: super .read();
146:
147: // Create the extension registry mementos.
148: final IExtensionRegistry registry = Platform
149: .getExtensionRegistry();
150: int commandDefinitionCount = 0;
151: int handlerDefinitionCount = 0;
152: int handlerSubmissionCount = 0;
153: final IConfigurationElement[][] indexedConfigurationElements = new IConfigurationElement[3][];
154:
155: // Sort the commands extension point based on element name.
156: final IConfigurationElement[] commandsExtensionPoint = registry
157: .getConfigurationElementsFor(EXTENSION_COMMANDS);
158: for (int i = 0; i < commandsExtensionPoint.length; i++) {
159: final IConfigurationElement configurationElement = commandsExtensionPoint[i];
160: final String name = configurationElement.getName();
161:
162: // Check if it is a handler submission or a command definition.
163: if (TAG_HANDLER_SUBMISSION.equals(name)) {
164: addElementToIndexedArray(configurationElement,
165: indexedConfigurationElements,
166: INDEX_HANDLER_SUBMISSIONS,
167: handlerSubmissionCount++);
168: } else if (TAG_COMMAND.equals(name)) {
169: addElementToIndexedArray(configurationElement,
170: indexedConfigurationElements,
171: INDEX_COMMAND_DEFINITIONS,
172: commandDefinitionCount++);
173: }
174: }
175:
176: // Sort the handler extension point based on element name.
177: final IConfigurationElement[] handlersExtensionPoint = registry
178: .getConfigurationElementsFor(EXTENSION_HANDLERS);
179: for (int i = 0; i < handlersExtensionPoint.length; i++) {
180: final IConfigurationElement configurationElement = handlersExtensionPoint[i];
181: final String name = configurationElement.getName();
182:
183: // Check if it is a handler submission or a command definition.
184: if (TAG_HANDLER.equals(name)) {
185: addElementToIndexedArray(configurationElement,
186: indexedConfigurationElements,
187: INDEX_HANDLER_DEFINITIONS,
188: handlerDefinitionCount++);
189: }
190: }
191:
192: clearActivations(handlerService);
193: readDefaultHandlersFromRegistry(
194: indexedConfigurationElements[INDEX_COMMAND_DEFINITIONS],
195: commandDefinitionCount);
196: readHandlerSubmissionsFromRegistry(
197: indexedConfigurationElements[INDEX_HANDLER_SUBMISSIONS],
198: handlerSubmissionCount);
199: readHandlersFromRegistry(
200: indexedConfigurationElements[INDEX_HANDLER_DEFINITIONS],
201: handlerDefinitionCount);
202: }
203:
204: /**
205: * Reads the default handlers from an array of command elements from the
206: * commands extension point.
207: *
208: * @param configurationElements
209: * The configuration elements in the commands extension point;
210: * must not be <code>null</code>, but may be empty.
211: * @param configurationElementCount
212: * The number of configuration elements that are really in the
213: * array.
214: */
215: private final void readDefaultHandlersFromRegistry(
216: final IConfigurationElement[] configurationElements,
217: final int configurationElementCount) {
218: for (int i = 0; i < configurationElementCount; i++) {
219: final IConfigurationElement configurationElement = configurationElements[i];
220:
221: /*
222: * Read out the command identifier. This was already checked by
223: * <code>CommandPersistence</code>, so we'll just ignore any
224: * problems here.
225: */
226: final String commandId = readOptional(configurationElement,
227: ATT_ID);
228: if (commandId == null) {
229: continue;
230: }
231:
232: // Check to see if we have a default handler of any kind.
233: if ((configurationElement.getAttribute(ATT_DEFAULT_HANDLER) == null)
234: && (configurationElement
235: .getChildren(TAG_DEFAULT_HANDLER).length == 0)) {
236: continue;
237: }
238:
239: handlerActivations.add(handlerService.activateHandler(
240: commandId, new HandlerProxy(configurationElement,
241: ATT_DEFAULT_HANDLER)));
242: }
243: }
244:
245: /**
246: * Reads all of the handlers from the handlers extension point.
247: *
248: * @param configurationElements
249: * The configuration elements in the commands extension point;
250: * must not be <code>null</code>, but may be empty.
251: * @param configurationElementCount
252: * The number of configuration elements that are really in the
253: * array.
254: * @param handlerService
255: * The handler service to which the handlers should be added;
256: * must not be <code>null</code>.
257: */
258: private final void readHandlersFromRegistry(
259: final IConfigurationElement[] configurationElements,
260: final int configurationElementCount) {
261: final List warningsToLog = new ArrayList(1);
262:
263: for (int i = 0; i < configurationElementCount; i++) {
264: final IConfigurationElement configurationElement = configurationElements[i];
265:
266: // Read out the command identifier.
267: final String commandId = readRequired(configurationElement,
268: ATT_COMMAND_ID, warningsToLog,
269: "Handlers need a command id"); //$NON-NLS-1$
270: if (commandId == null) {
271: continue;
272: }
273:
274: // Check to see if we have a handler class.
275: if (!checkClass(configurationElement, warningsToLog,
276: "Handlers need a class", commandId)) { //$NON-NLS-1$
277: continue;
278: }
279:
280: // Get the activeWhen and enabledWhen expressions.
281: final Expression activeWhenExpression = readWhenElement(
282: configurationElement, TAG_ACTIVE_WHEN, commandId,
283: warningsToLog);
284: if (activeWhenExpression == ERROR_EXPRESSION) {
285: continue;
286: }
287: final Expression enabledWhenExpression = readWhenElement(
288: configurationElement, TAG_ENABLED_WHEN, commandId,
289: warningsToLog);
290: if (enabledWhenExpression == ERROR_EXPRESSION) {
291: continue;
292: }
293:
294: final IHandler proxy = new HandlerProxy(
295: configurationElement, ATT_CLASS,
296: enabledWhenExpression, evaluationService);
297: handlerActivations.add(handlerService.activateHandler(
298: commandId, proxy, activeWhenExpression));
299:
300: // Read out the help context identifier.
301: final String helpContextId = readOptional(
302: configurationElement, ATT_HELP_CONTEXT_ID);
303: handlerService.setHelpContextId(proxy, helpContextId);
304: }
305:
306: logWarnings(
307: warningsToLog,
308: "Warnings while parsing the handlers from the 'org.eclipse.ui.handlers' extension point."); //$NON-NLS-1$
309: }
310:
311: /**
312: * Reads all of the handler submissions from the commands extension point.
313: *
314: * @param configurationElements
315: * The configuration elements in the commands extension point;
316: * must not be <code>null</code>, but may be empty.
317: * @param configurationElementCount
318: * The number of configuration elements that are really in the
319: * array.
320: * @param handlerService
321: * The handler service to which the handlers should be added;
322: * must not be <code>null</code>.
323: */
324: private final void readHandlerSubmissionsFromRegistry(
325: final IConfigurationElement[] configurationElements,
326: final int configurationElementCount) {
327: final List warningsToLog = new ArrayList(1);
328:
329: for (int i = 0; i < configurationElementCount; i++) {
330: final IConfigurationElement configurationElement = configurationElements[i];
331:
332: // Read out the command identifier.
333: final String commandId = readRequired(configurationElement,
334: ATT_COMMAND_ID, warningsToLog,
335: "Handler submissions need a command id"); //$NON-NLS-1$
336: if (commandId == null) {
337: continue;
338: }
339:
340: handlerActivations.add(handlerService.activateHandler(
341: commandId,
342: new LegacyHandlerWrapper(new LegacyHandlerProxy(
343: configurationElement))));
344: }
345:
346: logWarnings(
347: warningsToLog,
348: "Warnings while parsing the handler submissions from the 'org.eclipse.ui.commands' extension point."); //$NON-NLS-1$
349: }
350: }
|