KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > services > PreferencePersistence


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.services;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.Collection JavaDoc;
16 import java.util.List JavaDoc;
17
18 import org.eclipse.core.commands.Command;
19 import org.eclipse.core.commands.IParameter;
20 import org.eclipse.core.commands.Parameterization;
21 import org.eclipse.core.commands.ParameterizedCommand;
22 import org.eclipse.core.commands.common.NotDefinedException;
23 import org.eclipse.core.runtime.IStatus;
24 import org.eclipse.core.runtime.Status;
25 import org.eclipse.jface.preference.IPreferenceStore;
26 import org.eclipse.jface.util.IPropertyChangeListener;
27 import org.eclipse.jface.util.PropertyChangeEvent;
28 import org.eclipse.ui.IMemento;
29 import org.eclipse.ui.commands.ICommandService;
30 import org.eclipse.ui.internal.WorkbenchPlugin;
31 import org.eclipse.ui.internal.util.Util;
32
33 /**
34  * <p>
35  * A manager for items parsed from the preference store. This attaches a
36  * listener to the registry after the first read, and monitors the preference
37  * for changes from that point on. When {@link #dispose()} is called, the
38  * listener is detached.
39  * </p>
40  * <p>
41  * This class is only intended for internal use within the
42  * <code>org.eclipse.ui.workbench</code> plug-in.
43  * </p>
44  *
45  * @since 3.2
46  */

47 public abstract class PreferencePersistence extends RegistryPersistence {
48
49     /**
50      * Inserts the given element into the indexed two-dimensional array in the
51      * array at the index. The array is grown as necessary.
52      *
53      * @param elementToAdd
54      * The element to add to the indexed array; may be
55      * <code>null</code>
56      * @param indexedArray
57      * The two-dimensional array that is indexed by element type;
58      * must not be <code>null</code>.
59      * @param index
60      * The index at which the element should be added; must be a
61      * valid index.
62      * @param currentCount
63      * The current number of items in the array at the index.
64      */

65     protected static final void addElementToIndexedArray(
66             final IMemento elementToAdd, final IMemento[][] indexedArray,
67             final int index, final int currentCount) {
68         final IMemento[] elements;
69         if (currentCount == 0) {
70             elements = new IMemento[1];
71             indexedArray[index] = elements;
72         } else {
73             if (currentCount >= indexedArray[index].length) {
74                 final IMemento[] copy = new IMemento[indexedArray[index].length * 2];
75                 System.arraycopy(indexedArray[index], 0, copy, 0, currentCount);
76                 elements = copy;
77                 indexedArray[index] = elements;
78             } else {
79                 elements = indexedArray[index];
80             }
81         }
82         elements[currentCount] = elementToAdd;
83     }
84
85     /**
86      * Adds a warning to be logged at some later point in time.
87      *
88      * @param warningsToLog
89      * The collection of warnings to be logged; must not be
90      * <code>null</code>.
91      * @param message
92      * The mesaage to log; must not be <code>null</code>.
93      */

94     protected static final void addWarning(final List JavaDoc warningsToLog,
95             final String JavaDoc message) {
96         addWarning(warningsToLog, message, null, null, null);
97     }
98
99     /**
100      * Adds a warning to be logged at some later point in time. This logs the
101      * identifier of the item.
102      *
103      * @param warningsToLog
104      * The collection of warnings to be logged; must not be
105      * <code>null</code>.
106      * @param message
107      * The mesaage to log; must not be <code>null</code>.
108      * @param id
109      * The identifier of the item for which a warning is being
110      * logged; may be <code>null</code>.
111      */

112     protected static final void addWarning(final List JavaDoc warningsToLog,
113             final String JavaDoc message, final String JavaDoc id) {
114         addWarning(warningsToLog, message, id, null, null);
115     }
116
117     /**
118      * Adds a warning to be logged at some later point in time. This logs the
119      * identifier of the item, as well as an extra attribute.
120      *
121      * @param warningsToLog
122      * The collection of warnings to be logged; must not be
123      * <code>null</code>.
124      * @param message
125      * The mesaage to log; must not be <code>null</code>.
126      * @param id
127      * The identifier of the item for which a warning is being
128      * logged; may be <code>null</code>.
129      * @param extraAttributeName
130      * The name of extra attribute to be logged; may be
131      * <code>null</code>.
132      * @param extraAttributeValue
133      * The value of the extra attribute to be logged; may be
134      * <code>null</code>.
135      */

136     protected static final void addWarning(final List JavaDoc warningsToLog,
137             final String JavaDoc message, final String JavaDoc id,
138             final String JavaDoc extraAttributeName, final String JavaDoc extraAttributeValue) {
139         String JavaDoc statusMessage = message;
140         if (id != null) {
141             statusMessage = statusMessage + ": id='" + id + '\''; //$NON-NLS-1$
142
}
143         if (extraAttributeName != null) {
144             if (id != null) {
145                 statusMessage = statusMessage + ',';
146             } else {
147                 statusMessage = statusMessage + ':';
148             }
149             statusMessage = statusMessage + ' ' + extraAttributeName + "='" //$NON-NLS-1$
150
+ extraAttributeValue + '\'';
151         }
152
153         final IStatus status = new Status(IStatus.WARNING,
154                 WorkbenchPlugin.PI_WORKBENCH, 0, statusMessage, null);
155         warningsToLog.add(status);
156     }
157
158     /**
159      * Reads a boolean attribute from a memnto.
160      *
161      * @param memento
162      * The memento from which to read the attribute; must not be
163      * <code>null</code>.
164      * @param attribute
165      * The attribute to read; must not be <code>null</code>.
166      * @param defaultValue
167      * The default boolean value.
168      * @return The attribute's value; may be <code>null</code> if none.
169      */

170     protected static final boolean readBoolean(final IMemento memento,
171             final String JavaDoc attribute, final boolean defaultValue) {
172         final String JavaDoc value = memento.getString(attribute);
173         if (value == null) {
174             return defaultValue;
175         }
176
177         if (defaultValue) {
178             return !value.equalsIgnoreCase("false"); //$NON-NLS-1$
179
}
180
181         return !value.equalsIgnoreCase("true"); //$NON-NLS-1$
182
}
183
184     /**
185      * Reads an optional attribute from a memento. This converts zero-length
186      * strings into <code>null</code>.
187      *
188      * @param memento
189      * The memento from which to read the attribute; must not be
190      * <code>null</code>.
191      * @param attribute
192      * The attribute to read; must not be <code>null</code>.
193      * @return The attribute's value; may be <code>null</code> if none.
194      */

195     protected static final String JavaDoc readOptional(final IMemento memento,
196             final String JavaDoc attribute) {
197         String JavaDoc value = memento.getString(attribute);
198         if ((value != null) && (value.length() == 0)) {
199             value = null;
200         }
201
202         return value;
203     }
204
205     /**
206      * Reads the parameterized command from a parent memento. This is used to
207      * read the parameter sub-elements from a key element, as well as the
208      * command id. Each parameter is guaranteed to be valid. If invalid
209      * parameters are found, then a warning status will be appended to the
210      * <code>warningsToLog</code> list. The command id is required, or a
211      * warning will be logged.
212      *
213      * @param memento
214      * The memento from which the parameters should be read; must not
215      * be <code>null</code>.
216      * @param commandService
217      * The service providing commands for the workbench; must not be
218      * <code>null</code>.
219      * @param warningsToLog
220      * The list of warnings found during parsing. Warnings found will
221      * parsing the parameters will be appended to this list. This
222      * value must not be <code>null</code>.
223      * @param message
224      * The message to print if the command identifier is not present;
225      * must not be <code>null</code>.
226      * @return The array of parameters found for this configuration element;
227      * <code>null</code> if none can be found.
228      */

229     protected static final ParameterizedCommand readParameterizedCommand(
230             final IMemento memento, final ICommandService commandService,
231             final List JavaDoc warningsToLog, final String JavaDoc message, final String JavaDoc id) {
232         final String JavaDoc commandId = readRequired(memento, ATT_COMMAND_ID,
233                 warningsToLog, message, id);
234         if (commandId == null) {
235             return null;
236         }
237
238         final Command command = commandService.getCommand(commandId);
239         final ParameterizedCommand parameterizedCommand = readParameters(
240                 memento, warningsToLog, command);
241
242         return parameterizedCommand;
243     }
244
245     /**
246      * Reads the parameters from a parent memento. This is used to read the
247      * parameter sub-elements from a key element. Each parameter is guaranteed
248      * to be valid. If invalid parameters are found, then a warning status will
249      * be appended to the <code>warningsToLog</code> list.
250      *
251      * @param memento
252      * The memento from which the parameters should be read; must not
253      * be <code>null</code>.
254      * @param warningsToLog
255      * The list of warnings found during parsing. Warnings found will
256      * parsing the parameters will be appended to this list. This
257      * value must not be <code>null</code>.
258      * @param command
259      * The command around which the parameterization should be
260      * created; must not be <code>null</code>.
261      * @return The array of parameters found for this memento; <code>null</code>
262      * if none can be found.
263      */

264     protected static final ParameterizedCommand readParameters(
265             final IMemento memento, final List JavaDoc warningsToLog,
266             final Command command) {
267         final IMemento[] parameterMementos = memento
268                 .getChildren(TAG_PARAMETER);
269         if ((parameterMementos == null) || (parameterMementos.length == 0)) {
270             return new ParameterizedCommand(command, null);
271         }
272
273         final Collection JavaDoc parameters = new ArrayList JavaDoc();
274         for (int i = 0; i < parameterMementos.length; i++) {
275             final IMemento parameterMemento = parameterMementos[i];
276
277             // Read out the id.
278
final String JavaDoc id = parameterMemento.getString(ATT_ID);
279             if ((id == null) || (id.length() == 0)) {
280                 // The name should never be null. This is invalid.
281
addWarning(warningsToLog, "Parameters need a name"); //$NON-NLS-1$
282
continue;
283             }
284
285             // Find the parameter on the command.
286
IParameter parameter = null;
287             try {
288                 final IParameter[] commandParameters = command.getParameters();
289                 if (parameters != null) {
290                     for (int j = 0; j < commandParameters.length; j++) {
291                         final IParameter currentParameter = commandParameters[j];
292                         if (Util.equals(currentParameter.getId(), id)) {
293                             parameter = currentParameter;
294                             break;
295                         }
296                     }
297
298                 }
299             } catch (final NotDefinedException e) {
300                 // This should not happen.
301
}
302             if (parameter == null) {
303                 // The name should never be null. This is invalid.
304
addWarning(warningsToLog,
305                         "Could not find a matching parameter", id); //$NON-NLS-1$
306
continue;
307             }
308
309             // Read out the value.
310
final String JavaDoc value = parameterMemento.getString(ATT_VALUE);
311             if ((value == null) || (value.length() == 0)) {
312                 // The name should never be null. This is invalid.
313
addWarning(warningsToLog, "Parameters need a value", id); //$NON-NLS-1$
314
continue;
315             }
316
317             parameters.add(new Parameterization(parameter, value));
318         }
319
320         if (parameters.isEmpty()) {
321             return new ParameterizedCommand(command, null);
322         }
323
324         return new ParameterizedCommand(command,
325                 (Parameterization[]) parameters
326                         .toArray(new Parameterization[parameters.size()]));
327     }
328
329     /**
330      * Reads a required attribute from the memento.
331      *
332      * @param memento
333      * The memento from which to read; must not be <code>null</code>.
334      * @param attribute
335      * The attribute to read; must not be <code>null</code>.
336      * @param warningsToLog
337      * The list of warnings; must not be <code>null</code>.
338      * @param message
339      * The warning message to use if the attribute is missing; must
340      * not be <code>null</code>.
341      * @return The required attribute; may be <code>null</code> if missing.
342      */

343     protected static final String JavaDoc readRequired(final IMemento memento,
344             final String JavaDoc attribute, final List JavaDoc warningsToLog,
345             final String JavaDoc message) {
346         return readRequired(memento, attribute, warningsToLog, message, null);
347     }
348
349     /**
350      * Reads a required attribute from the memento. This logs the identifier of
351      * the item if this required element cannot be found.
352      *
353      * @param memento
354      * The memento from which to read; must not be <code>null</code>.
355      * @param attribute
356      * The attribute to read; must not be <code>null</code>.
357      * @param warningsToLog
358      * The list of warnings; must not be <code>null</code>.
359      * @param message
360      * The warning message to use if the attribute is missing; must
361      * not be <code>null</code>.
362      * @param id
363      * The identifier of the element for which this is a required
364      * attribute; may be <code>null</code>.
365      * @return The required attribute; may be <code>null</code> if missing.
366      */

367     protected static final String JavaDoc readRequired(final IMemento memento,
368             final String JavaDoc attribute, final List JavaDoc warningsToLog,
369             final String JavaDoc message, final String JavaDoc id) {
370         final String JavaDoc value = memento.getString(attribute);
371         if ((value == null) || (value.length() == 0)) {
372             addWarning(warningsToLog, message, id);
373             return null;
374         }
375
376         return value;
377     }
378
379     /**
380      * Whether the preference and registry change listeners have been attached
381      * yet.
382      */

383     protected boolean preferenceListenerAttached = false;
384
385     /**
386      * The registry change listener for this class.
387      */

388     private final IPropertyChangeListener preferenceChangeListener;
389
390     /**
391      * Detaches the preference change listener from the registry.
392      */

393     public final void dispose() {
394         super.dispose();
395
396         final IPreferenceStore store = WorkbenchPlugin.getDefault()
397                 .getPreferenceStore();
398         store.removePropertyChangeListener(preferenceChangeListener);
399     }
400
401     /**
402      * Checks whether the preference change could affect this persistence class.
403      *
404      * @param event
405      * The event indicating the preference change; must not be
406      * <code>null</code>.
407      * @return <code>true</code> if the persistence instance is affected by
408      * this change; <code>false</code> otherwise.
409      */

410     protected abstract boolean isChangeImportant(final PropertyChangeEvent event);
411
412     /**
413      * Reads the various elements from the registry. Subclasses should extend,
414      * but must not override.
415      */

416     protected void read() {
417         super.read();
418
419         if (!preferenceListenerAttached) {
420             final IPreferenceStore store = WorkbenchPlugin.getDefault()
421                     .getPreferenceStore();
422             store.addPropertyChangeListener(preferenceChangeListener);
423         }
424     }
425
426     /**
427      * Constructs a new instance of {@link PreferencePersistence}. A preference
428      * change listener is created.
429      */

430     protected PreferencePersistence() {
431         super();
432
433         preferenceChangeListener = new IPropertyChangeListener() {
434             public final void propertyChange(final PropertyChangeEvent event) {
435                 if (isChangeImportant(event)) {
436                     read();
437                 }
438             }
439         };
440     }
441 }
442
Popular Tags