KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > commands > CommandPersistence


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

11
12 package org.eclipse.ui.internal.commands;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.core.commands.AbstractParameterValueConverter;
18 import org.eclipse.core.commands.Category;
19 import org.eclipse.core.commands.Command;
20 import org.eclipse.core.commands.ParameterType;
21 import org.eclipse.core.commands.State;
22 import org.eclipse.core.commands.common.HandleObject;
23 import org.eclipse.core.runtime.IConfigurationElement;
24 import org.eclipse.core.runtime.IExtensionDelta;
25 import org.eclipse.core.runtime.IExtensionRegistry;
26 import org.eclipse.core.runtime.IRegistryChangeEvent;
27 import org.eclipse.core.runtime.Platform;
28 import org.eclipse.ui.PlatformUI;
29 import org.eclipse.ui.commands.ICommandService;
30 import org.eclipse.ui.internal.WorkbenchMessages;
31 import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
32 import org.eclipse.ui.internal.services.RegistryPersistence;
33 import org.eclipse.ui.internal.util.PrefUtil;
34
35 /**
36  * <p>
37  * A static class for accessing the registry and the preference store.
38  * </p>
39  *
40  * @since 3.1
41  */

42 final class CommandPersistence extends RegistryPersistence {
43
44     /**
45      * The index of the category elements in the indexed array.
46      *
47      * @see CommandPersistence#read()
48      */

49     private static final int INDEX_CATEGORY_DEFINITIONS = 0;
50
51     /**
52      * The index of the command elements in the indexed array.
53      *
54      * @see CommandPersistence#read()
55      */

56     private static final int INDEX_COMMAND_DEFINITIONS = 1;
57
58     /**
59      * The index of the commandParameterType elements in the indexed array.
60      *
61      * @see CommandPersistence#read()
62      * @since 3.2
63      */

64     private static final int INDEX_PARAMETER_TYPE_DEFINITIONS = 2;
65
66     /**
67      * Reads all of the category definitions from the commands extension point.
68      *
69      * @param configurationElements
70      * The configuration elements in the commands extension point;
71      * must not be <code>null</code>, but may be empty.
72      * @param configurationElementCount
73      * The number of configuration elements that are really in the
74      * array.
75      * @param commandService
76      * The command service to which the categories should be added;
77      * must not be <code>null</code>.
78      */

79     private static final void readCategoriesFromRegistry(
80             final IConfigurationElement[] configurationElements,
81             final int configurationElementCount,
82             final ICommandService commandService) {
83         // Undefine all the previous handle objects.
84
final HandleObject[] handleObjects = commandService
85                 .getDefinedCategories();
86         if (handleObjects != null) {
87             for (int i = 0; i < handleObjects.length; i++) {
88                 handleObjects[i].undefine();
89             }
90         }
91
92         // Define the uncategorized category.
93
commandService
94                 .defineUncategorizedCategory(
95                         WorkbenchMessages.CommandService_AutogeneratedCategoryName,
96                         WorkbenchMessages.CommandService_AutogeneratedCategoryDescription);
97
98         final List JavaDoc warningsToLog = new ArrayList JavaDoc(1);
99
100         for (int i = 0; i < configurationElementCount; i++) {
101             final IConfigurationElement configurationElement = configurationElements[i];
102
103             // Read out the category identifier.
104
final String JavaDoc categoryId = readRequired(configurationElement,
105                     ATT_ID, warningsToLog, "Categories need an id"); //$NON-NLS-1$
106
if (categoryId == null) {
107                 continue;
108             }
109
110             // Read out the name.
111
final String JavaDoc name = readRequired(configurationElement, ATT_NAME,
112                     warningsToLog, "Categories need a name", //$NON-NLS-1$
113
categoryId);
114             if (name == null) {
115                 continue;
116             }
117
118             // Read out the description.
119
final String JavaDoc description = readOptional(configurationElement,
120                     ATT_DESCRIPTION);
121
122             final Category category = commandService.getCategory(categoryId);
123             category.define(name, description);
124         }
125
126         // If there were any warnings, then log them now.
127
logWarnings(
128                 warningsToLog,
129                 "Warnings while parsing the commands from the 'org.eclipse.ui.commands' and 'org.eclipse.ui.actionDefinitions' extension points."); //$NON-NLS-1$
130
}
131
132     /**
133      * Reads all of the command definitions from the commands extension point.
134      *
135      * @param configurationElements
136      * The configuration elements in the commands extension point;
137      * must not be <code>null</code>, but may be empty.
138      * @param configurationElementCount
139      * The number of configuration elements that are really in the
140      * array.
141      * @param commandService
142      * The command service to which the commands should be added;
143      * must not be <code>null</code>.
144      */

145     private static final void readCommandsFromRegistry(
146             final IConfigurationElement[] configurationElements,
147             final int configurationElementCount,
148             final ICommandService commandService) {
149         // Undefine all the previous handle objects.
150
final HandleObject[] handleObjects = commandService
151                 .getDefinedCommands();
152         if (handleObjects != null) {
153             for (int i = 0; i < handleObjects.length; i++) {
154                 handleObjects[i].undefine();
155             }
156         }
157
158         final List JavaDoc warningsToLog = new ArrayList JavaDoc(1);
159
160         for (int i = 0; i < configurationElementCount; i++) {
161             final IConfigurationElement configurationElement = configurationElements[i];
162
163             // Read out the command identifier.
164
final String JavaDoc commandId = readRequired(configurationElement, ATT_ID,
165                     warningsToLog, "Commands need an id"); //$NON-NLS-1$
166
if (commandId == null) {
167                 continue;
168             }
169
170             // Read out the name.
171
final String JavaDoc name = readRequired(configurationElement, ATT_NAME,
172                     warningsToLog, "Commands need a name"); //$NON-NLS-1$
173
if (name == null) {
174                 continue;
175             }
176
177             // Read out the description.
178
final String JavaDoc description = readOptional(configurationElement,
179                     ATT_DESCRIPTION);
180
181             // Read out the category id.
182
String JavaDoc categoryId = configurationElement
183                     .getAttribute(ATT_CATEGORY_ID);
184             if ((categoryId == null) || (categoryId.length() == 0)) {
185                 categoryId = configurationElement.getAttribute(ATT_CATEGORY);
186                 if ((categoryId != null) && (categoryId.length() == 0)) {
187                     categoryId = null;
188                 }
189             }
190
191             // Read out the parameters.
192
final Parameter[] parameters = readParameters(configurationElement,
193                     warningsToLog, commandService);
194
195             // Read out the returnTypeId.
196
final String JavaDoc returnTypeId = readOptional(configurationElement,
197                     ATT_RETURN_TYPE_ID);
198
199             // Read out the help context identifier.
200
final String JavaDoc helpContextId = readOptional(configurationElement,
201                     ATT_HELP_CONTEXT_ID);
202
203             final Command command = commandService.getCommand(commandId);
204             final Category category = commandService.getCategory(categoryId);
205             if (!category.isDefined()) {
206                 addWarning(
207                         warningsToLog,
208                         "Commands should really have a category", //$NON-NLS-1$
209
configurationElement, commandId,
210                         "categoryId", categoryId); //$NON-NLS-1$
211
}
212
213             final ParameterType returnType;
214             if (returnTypeId == null) {
215                 returnType = null;
216             } else {
217                 returnType = commandService.getParameterType(returnTypeId);
218             }
219
220             command.define(name, description, category, parameters, returnType,
221                     helpContextId);
222             readState(configurationElement, warningsToLog, command);
223         }
224
225         // If there were any warnings, then log them now.
226
logWarnings(
227                 warningsToLog,
228                 "Warnings while parsing the commands from the 'org.eclipse.ui.commands' and 'org.eclipse.ui.actionDefinitions' extension points."); //$NON-NLS-1$
229
}
230
231     /**
232      * Reads the parameters from a parent configuration element. This is used to
233      * read the parameter sub-elements from a command element. Each parameter is
234      * guaranteed to be valid. If invalid parameters are found, then a warning
235      * status will be appended to the <code>warningsToLog</code> list.
236      *
237      * @param configurationElement
238      * The configuration element from which the parameters should be
239      * read; must not be <code>null</code>.
240      * @param warningsToLog
241      * The list of warnings found during parsing. Warnings found
242      * while parsing the parameters will be appended to this list.
243      * This value must not be <code>null</code>.
244      * @param commandService
245      * The command service from which the parameter can get parameter
246      * types; must not be <code>null</code>.
247      * @return The array of parameters found for this configuration element;
248      * <code>null</code> if none can be found.
249      */

250     private static final Parameter[] readParameters(
251             final IConfigurationElement configurationElement,
252             final List JavaDoc warningsToLog, final ICommandService commandService) {
253         final IConfigurationElement[] parameterElements = configurationElement
254                 .getChildren(TAG_COMMAND_PARAMETER);
255         if ((parameterElements == null) || (parameterElements.length == 0)) {
256             return null;
257         }
258
259         int insertionIndex = 0;
260         Parameter[] parameters = new Parameter[parameterElements.length];
261         for (int i = 0; i < parameterElements.length; i++) {
262             final IConfigurationElement parameterElement = parameterElements[i];
263             // Read out the id
264
final String JavaDoc id = readRequired(parameterElement, ATT_ID,
265                     warningsToLog, "Parameters need an id"); //$NON-NLS-1$
266
if (id == null) {
267                 continue;
268             }
269
270             // Read out the name.
271
final String JavaDoc name = readRequired(parameterElement, ATT_NAME,
272                     warningsToLog, "Parameters need a name"); //$NON-NLS-1$
273
if (name == null) {
274                 continue;
275             }
276
277             /*
278              * The IParameterValues will be initialized lazily as an
279              * IExecutableExtension.
280              */

281
282             // Read out the typeId attribute, if present.
283
final String JavaDoc typeId = readOptional(parameterElement, ATT_TYPE_ID);
284
285             // Read out the optional attribute, if present.
286
final boolean optional = readBoolean(parameterElement,
287                     ATT_OPTIONAL, true);
288
289             final ParameterType type;
290             if (typeId == null) {
291                 type = null;
292             } else {
293                 type = commandService.getParameterType(typeId);
294             }
295
296             final Parameter parameter = new Parameter(id, name,
297                     parameterElement, type, optional);
298             parameters[insertionIndex++] = parameter;
299         }
300
301         if (insertionIndex != parameters.length) {
302             final Parameter[] compactedParameters = new Parameter[insertionIndex];
303             System.arraycopy(parameters, 0, compactedParameters, 0,
304                     insertionIndex);
305             parameters = compactedParameters;
306         }
307
308         return parameters;
309     }
310
311     /**
312      * Reads all of the commandParameterType definitions from the commands
313      * extension point.
314      *
315      * @param configurationElements
316      * The configuration elements in the commands extension point;
317      * must not be <code>null</code>, but may be empty.
318      * @param configurationElementCount
319      * The number of configuration elements that are really in the
320      * array.
321      * @param commandService
322      * The command service to which the commands should be added;
323      * must not be <code>null</code>.
324      * @since 3.2
325      */

326     private static final void readParameterTypesFromRegistry(
327             final IConfigurationElement[] configurationElements,
328             final int configurationElementCount,
329             final ICommandService commandService) {
330
331         // Undefine all the previous handle objects.
332
final HandleObject[] handleObjects = commandService
333                 .getDefinedParameterTypes();
334         if (handleObjects != null) {
335             for (int i = 0; i < handleObjects.length; i++) {
336                 handleObjects[i].undefine();
337             }
338         }
339
340         final List JavaDoc warningsToLog = new ArrayList JavaDoc(1);
341
342         for (int i = 0; i < configurationElementCount; i++) {
343             final IConfigurationElement configurationElement = configurationElements[i];
344
345             // Read out the commandParameterType identifier.
346
final String JavaDoc parameterTypeId = readRequired(configurationElement,
347                     ATT_ID, warningsToLog, "Command parameter types need an id"); //$NON-NLS-1$
348
if (parameterTypeId == null) {
349                 continue;
350             }
351
352             // Read out the type.
353
final String JavaDoc type = readOptional(configurationElement, ATT_TYPE);
354
355             // Read out the converter.
356
final String JavaDoc converter = readOptional(configurationElement,
357                     ATT_CONVERTER);
358
359             /*
360              * if the converter attribute was given, create a proxy
361              * AbstractParameterValueConverter for the ParameterType, otherwise
362              * null indicates there is no converter
363              */

364             final AbstractParameterValueConverter parameterValueConverter = (converter == null) ? null
365                     : new ParameterValueConverterProxy(configurationElement);
366
367             final ParameterType parameterType = commandService
368                     .getParameterType(parameterTypeId);
369             parameterType.define(type, parameterValueConverter);
370         }
371
372         // If there were any warnings, then log them now.
373
logWarnings(
374                 warningsToLog,
375                 "Warnings while parsing the commandParameterTypes from the 'org.eclipse.ui.commands' extension point."); //$NON-NLS-1$
376

377     }
378
379     /**
380      * Reads the states from a parent configuration element. This is used to
381      * read the state sub-elements from a command element. Each state is
382      * guaranteed to be valid. If invalid states are found, then a warning
383      * status will be appended to the <code>warningsToLog</code> list.
384      *
385      * @param configurationElement
386      * The configuration element from which the states should be
387      * read; must not be <code>null</code>.
388      * @param warningsToLog
389      * The list of warnings found during parsing. Warnings found
390      * while parsing the parameters will be appended to this list.
391      * This value must not be <code>null</code>.
392      * @param command
393      * The command for which the state is being read; may be
394      * <code>null</code>.
395      */

396     private static final void readState(
397             final IConfigurationElement configurationElement,
398             final List JavaDoc warningsToLog, final Command command) {
399         final IConfigurationElement[] stateElements = configurationElement
400                 .getChildren(TAG_STATE);
401         if ((stateElements == null) || (stateElements.length == 0)) {
402             return;
403         }
404
405         for (int i = 0; i < stateElements.length; i++) {
406             final IConfigurationElement stateElement = stateElements[i];
407
408             final String JavaDoc id = readRequired(stateElement, ATT_ID, warningsToLog,
409                     "State needs an id"); //$NON-NLS-1$
410
if (id == null) {
411                 continue;
412             }
413
414             if (checkClass(stateElement, warningsToLog,
415                     "State must have an associated class", id)) { //$NON-NLS-1$
416
final State state = new CommandStateProxy(stateElement,
417                         ATT_CLASS, PrefUtil.getInternalPreferenceStore(),
418                         CommandService.createPreferenceKey(command, id));
419                 command.addState(id, state);
420             }
421         }
422     }
423
424     /**
425      * The command service with which this persistence class is associated;
426      * never <code>null</code>.
427      */

428     private final ICommandService commandService;
429
430     /**
431      * Constructs a new instance of <code>CommandPersistence</code>.
432      *
433      * @param commandService
434      * The command service which should be populated with the values
435      * from the registry; must not be <code>null</code>.
436      */

437     CommandPersistence(final ICommandService commandService) {
438         if (commandService == null) {
439             throw new NullPointerException JavaDoc("The command service cannot be null"); //$NON-NLS-1$
440
}
441         this.commandService = commandService;
442     }
443
444     protected final boolean isChangeImportant(final IRegistryChangeEvent event) {
445         final IExtensionDelta[] commandDeltas = event.getExtensionDeltas(
446                 PlatformUI.PLUGIN_ID, IWorkbenchRegistryConstants.PL_COMMANDS);
447         if (commandDeltas.length == 0) {
448             final IExtensionDelta[] actionDefinitionDeltas = event
449                     .getExtensionDeltas(PlatformUI.PLUGIN_ID,
450                             IWorkbenchRegistryConstants.PL_ACTION_DEFINITIONS);
451             if (actionDefinitionDeltas.length == 0) {
452                 return false;
453             }
454         }
455
456         return true;
457     }
458
459     /**
460      * Reads all of the commands and categories from the registry,
461      *
462      * @param commandService
463      * The command service which should be populated with the values
464      * from the registry; must not be <code>null</code>.
465      */

466     protected final void read() {
467         super.read();
468
469         // Create the extension registry mementos.
470
final IExtensionRegistry registry = Platform.getExtensionRegistry();
471         int commandDefinitionCount = 0;
472         int categoryDefinitionCount = 0;
473         int parameterTypeDefinitionCount = 0;
474         final IConfigurationElement[][] indexedConfigurationElements = new IConfigurationElement[3][];
475
476         // Sort the commands extension point based on element name.
477
final IConfigurationElement[] commandsExtensionPoint = registry
478                 .getConfigurationElementsFor(EXTENSION_COMMANDS);
479         for (int i = 0; i < commandsExtensionPoint.length; i++) {
480             final IConfigurationElement configurationElement = commandsExtensionPoint[i];
481             final String JavaDoc name = configurationElement.getName();
482
483             // Check if it is a binding definition.
484
if (TAG_COMMAND.equals(name)) {
485                 addElementToIndexedArray(configurationElement,
486                         indexedConfigurationElements,
487                         INDEX_COMMAND_DEFINITIONS, commandDefinitionCount++);
488             } else if (TAG_CATEGORY.equals(name)) {
489                 addElementToIndexedArray(configurationElement,
490                         indexedConfigurationElements,
491                         INDEX_CATEGORY_DEFINITIONS, categoryDefinitionCount++);
492             } else if (TAG_COMMAND_PARAMETER_TYPE.equals(name)) {
493                 addElementToIndexedArray(configurationElement,
494                         indexedConfigurationElements,
495                         INDEX_PARAMETER_TYPE_DEFINITIONS,
496                         parameterTypeDefinitionCount++);
497             }
498         }
499
500         final IConfigurationElement[] actionDefinitionsExtensionPoint = registry
501                 .getConfigurationElementsFor(EXTENSION_ACTION_DEFINITIONS);
502         for (int i = 0; i < actionDefinitionsExtensionPoint.length; i++) {
503             final IConfigurationElement configurationElement = actionDefinitionsExtensionPoint[i];
504             final String JavaDoc name = configurationElement.getName();
505
506             if (TAG_ACTION_DEFINITION.equals(name)) {
507                 addElementToIndexedArray(configurationElement,
508                         indexedConfigurationElements,
509                         INDEX_COMMAND_DEFINITIONS, commandDefinitionCount++);
510             }
511         }
512
513         readCategoriesFromRegistry(
514                 indexedConfigurationElements[INDEX_CATEGORY_DEFINITIONS],
515                 categoryDefinitionCount, commandService);
516         readCommandsFromRegistry(
517                 indexedConfigurationElements[INDEX_COMMAND_DEFINITIONS],
518                 commandDefinitionCount, commandService);
519         readParameterTypesFromRegistry(
520                 indexedConfigurationElements[INDEX_PARAMETER_TYPE_DEFINITIONS],
521                 parameterTypeDefinitionCount, commandService);
522
523     }
524 }
525
Popular Tags