KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > preferences > PreferenceForwarder


1 /*******************************************************************************
2  * Copyright (c) 2004, 2005 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 package org.eclipse.core.internal.preferences;
12
13 import java.io.*;
14 import java.util.Iterator JavaDoc;
15 import java.util.Properties JavaDoc;
16 import org.eclipse.core.internal.runtime.InternalPlatform;
17 import org.eclipse.core.runtime.*;
18 import org.eclipse.core.runtime.preferences.DefaultScope;
19 import org.eclipse.core.runtime.preferences.IEclipsePreferences;
20 import org.osgi.service.prefs.BackingStoreException;
21
22 /**
23  * This class represents a convenience layer between the Eclipse 3.0
24  * preferences and pre-3.0 preferences. It acts as a bridge between the
25  * org.eclipse.core.runtime.Preferences object associated with a particular plug-in
26  * object, and its corresponding preference node in the 3.0 preference node
27  * hierarchy.
28  *
29  * @since 3.0
30  */

31 public class PreferenceForwarder extends Preferences implements IEclipsePreferences.IPreferenceChangeListener, IEclipsePreferences.INodeChangeListener {
32
33     private static final byte[] BYTE_ARRAY_DEFAULT_DEFAULT = new byte[0];
34
35     private IEclipsePreferences pluginRoot = (IEclipsePreferences) Platform.getPreferencesService().getRootNode().node(Plugin.PLUGIN_PREFERENCE_SCOPE);
36     private DefaultPreferences defaultsRoot = (DefaultPreferences) Platform.getPreferencesService().getRootNode().node(DefaultScope.SCOPE);
37     private String JavaDoc pluginID;
38     private Plugin plugin;
39     // boolean to check to see if we should re-wrap and forward change
40
// events coming from the new runtime APIs.
41
private boolean notify = true;
42
43     /*
44      * Used for test suites only.
45      */

46     public PreferenceForwarder(String JavaDoc pluginID) {
47         this(null, pluginID);
48     }
49
50     public PreferenceForwarder(Plugin plugin, String JavaDoc pluginID) {
51         super();
52         this.plugin = plugin;
53         this.pluginID = pluginID;
54         pluginRoot.addNodeChangeListener(this);
55     }
56
57     /*
58      * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener#added(org.eclipse.core.runtime.preferences.IEclipsePreferences.NodeChangeEvent)
59      */

60     public void added(IEclipsePreferences.NodeChangeEvent event) {
61         if (listeners.size() > 0 && pluginID.equals(event.getChild().name()))
62             getPluginPreferences(true).addPreferenceChangeListener(this);
63     }
64
65     /*
66      * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener#removed(org.eclipse.core.runtime.preferences.IEclipsePreferences.NodeChangeEvent)
67      */

68     public void removed(IEclipsePreferences.NodeChangeEvent event) {
69         // don't worry about removing the preference change listener since
70
// we won't get any notification from a removed node anyways.
71
}
72
73     /**
74      * Adds a property change listener to this preference object.
75      * Has no affect if the identical listener is already registered.
76      *
77      * @param listener a property change listener
78      */

79     public void addPropertyChangeListener(IPropertyChangeListener listener) {
80         getPluginPreferences(true).addPreferenceChangeListener(this);
81         listeners.add(listener);
82     }
83
84     /*
85      * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener#preferenceChange(org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent)
86      */

87     public void preferenceChange(IEclipsePreferences.PreferenceChangeEvent event) {
88         // if we are the ones making this change, then don't broadcast
89
if (!notify)
90             return;
91         Object JavaDoc oldValue = event.getOldValue();
92         Object JavaDoc newValue = event.getNewValue();
93         String JavaDoc key = event.getKey();
94         if (newValue == null)
95             newValue = getDefault(key, oldValue);
96         else if (oldValue == null)
97             oldValue = getDefault(key, newValue);
98         firePropertyChangeEvent(key, oldValue, newValue);
99     }
100
101     private EclipsePreferences getPluginPreferences(boolean create) {
102         try {
103             if (!create && !pluginRoot.nodeExists(pluginID))
104                 return null;
105         } catch (BackingStoreException e) {
106             return null;
107         }
108         try {
109             return (EclipsePreferences) pluginRoot.node(pluginID);
110         } catch (ClassCastException JavaDoc e) {
111             throw new RuntimeException JavaDoc("Plug-in preferences must be instances of EclipsePreferences: " + e.getMessage()); //$NON-NLS-1$
112
}
113     }
114
115     private IEclipsePreferences getDefaultPreferences() {
116         return defaultsRoot.node(pluginID, plugin);
117     }
118
119     /**
120      * Removes the given listener from this preference object.
121      * Has no affect if the listener is not registered.
122      *
123      * @param listener a property change listener
124      */

125     public void removePropertyChangeListener(IPropertyChangeListener listener) {
126         listeners.remove(listener);
127     }
128
129     /**
130      * Does its best at determining the default value for the given key. Checks the
131      * given object's type and then looks in the list of defaults to see if a value
132      * exists. If not or if there is a problem converting the value, the default default
133      * value for that type is returned.
134      */

135     private Object JavaDoc getDefault(String JavaDoc key, Object JavaDoc obj) {
136         IEclipsePreferences defaults = getDefaultPreferences();
137         if (obj instanceof String JavaDoc)
138             return defaults.get(key, STRING_DEFAULT_DEFAULT);
139         else if (obj instanceof Integer JavaDoc)
140             return new Integer JavaDoc(defaults.getInt(key, INT_DEFAULT_DEFAULT));
141         else if (obj instanceof Double JavaDoc)
142             return new Double JavaDoc(defaults.getDouble(key, DOUBLE_DEFAULT_DEFAULT));
143         else if (obj instanceof Float JavaDoc)
144             return new Float JavaDoc(defaults.getFloat(key, FLOAT_DEFAULT_DEFAULT));
145         else if (obj instanceof Long JavaDoc)
146             return new Long JavaDoc(defaults.getLong(key, LONG_DEFAULT_DEFAULT));
147         else if (obj instanceof byte[])
148             return defaults.getByteArray(key, BYTE_ARRAY_DEFAULT_DEFAULT);
149         else if (obj instanceof Boolean JavaDoc)
150             return new Boolean JavaDoc(defaults.getBoolean(key, BOOLEAN_DEFAULT_DEFAULT));
151         else
152             return null;
153     }
154
155     /**
156      * Returns whether the given property is known to this preference object,
157      * either by having an explicit setting or by having a default
158      * setting.
159      *
160      * @param name the name of the property
161      * @return <code>true</code> if either a current value or a default
162      * value is known for the named property, and <code>false</code>otherwise
163      */

164     public boolean contains(String JavaDoc name) {
165         if (name == null)
166             return false;
167         String JavaDoc value = getPluginPreferences(true).get(name, null);
168         if (value != null)
169             return true;
170         return getDefaultPreferences().get(name, null) != null;
171     }
172
173     /**
174      * Returns the current value of the boolean-valued property with the
175      * given name.
176      * Returns the default-default value (<code>false</code>) if there
177      * is no property with the given name, or if the current value
178      * cannot be treated as a boolean.
179      *
180      * @param name the name of the property
181      * @return the boolean-valued property
182      */

183     public boolean getBoolean(String JavaDoc name) {
184         return getPluginPreferences(true).getBoolean(name, getDefaultPreferences().getBoolean(name, BOOLEAN_DEFAULT_DEFAULT));
185     }
186
187     /**
188      * Sets the current value of the boolean-valued property with the
189      * given name.
190      * <p>
191      * A property change event is reported if the current value of the
192      * property actually changes from its previous value. In the event
193      * object, the property name is the name of the property, and the
194      * old and new values are wrapped as objects.
195      * </p>
196      * <p>
197      * If the given value is the same as the corresponding default value
198      * for the given property, the explicit setting is deleted.
199      * Note that the recommended way of re-initializing a property to its
200      * default value is to call <code>setToDefault</code>.
201      * </p>
202      *
203      * @param name the name of the property
204      * @param value the new current value of the property
205      */

206     public void setValue(String JavaDoc name, boolean value) {
207         Boolean JavaDoc oldValue = getBoolean(name) ? Boolean.TRUE : Boolean.FALSE;
208         Boolean JavaDoc newValue = value ? Boolean.TRUE : Boolean.FALSE;
209         if (newValue == oldValue)
210             return;
211         try {
212             notify = false;
213             if (getDefaultBoolean(name) == value)
214                 getPluginPreferences(true).remove(name);
215             else
216                 getPluginPreferences(true).putBoolean(name, value);
217             firePropertyChangeEvent(name, oldValue, newValue);
218         } finally {
219             notify = true;
220         }
221     }
222
223     /**
224      * Returns the default value for the boolean-valued property
225      * with the given name.
226      * Returns the default-default value (<code>false</code>) if there
227      * is no default property with the given name, or if the default
228      * value cannot be treated as a boolean.
229      *
230      * @param name the name of the property
231      * @return the default value of the named property
232      */

233     public boolean getDefaultBoolean(String JavaDoc name) {
234         return getDefaultPreferences().getBoolean(name, BOOLEAN_DEFAULT_DEFAULT);
235     }
236
237     /**
238      * Sets the default value for the boolean-valued property with the
239      * given name.
240      * <p>
241      * Note that the current value of the property is affected if
242      * the property's current value was its old default value, in which
243      * case it changes to the new default value. If the property's current
244      * is different from its old default value, its current value is
245      * unaffected. No property change events are reported by changing default
246      * values.
247      * </p>
248      *
249      * @param name the name of the property
250      * @param value the new default value for the property
251      */

252     public void setDefault(String JavaDoc name, boolean value) {
253         getDefaultPreferences().putBoolean(name, value);
254     }
255
256     /**
257      * Returns the current value of the double-valued property with the
258      * given name.
259      * Returns the default-default value (<code>0.0</code>) if there
260      * is no property with the given name, or if the current value
261      * cannot be treated as a double.
262      *
263      * @param name the name of the property
264      * @return the double-valued property
265      */

266     public double getDouble(String JavaDoc name) {
267         return getPluginPreferences(true).getDouble(name, getDefaultPreferences().getDouble(name, DOUBLE_DEFAULT_DEFAULT));
268     }
269
270     /**
271      * Sets the current value of the double-valued property with the
272      * given name.
273      * <p>
274      * A property change event is reported if the current value of the
275      * property actually changes from its previous value. In the event
276      * object, the property name is the name of the property, and the
277      * old and new values are wrapped as objects.
278      * </p>
279      * <p>
280      * If the given value is the same as the corresponding default value
281      * for the given property, the explicit setting is deleted.
282      * Note that the recommended way of re-initializing a property to its
283      * default value is to call <code>setToDefault</code>.
284      * </p>
285      *
286      * @param name the name of the property
287      * @param value the new current value of the property; must be
288      * a number (not a NaN)
289      */

290     public void setValue(String JavaDoc name, double value) {
291         if (Double.isNaN(value))
292             throw new IllegalArgumentException JavaDoc();
293         final double doubleValue = getDouble(name);
294         if (value == doubleValue)
295             return;
296         Double JavaDoc oldValue = new Double JavaDoc(doubleValue);
297         Double JavaDoc newValue = new Double JavaDoc(value);
298         try {
299             notify = false;
300             if (getDefaultDouble(name) == value)
301                 getPluginPreferences(true).remove(name);
302             else
303                 getPluginPreferences(true).putDouble(name, value);
304             firePropertyChangeEvent(name, oldValue, newValue);
305         } finally {
306             notify = true;
307         }
308     }
309
310     /**
311      * Returns the default value for the double-valued property
312      * with the given name.
313      * Returns the default-default value (<code>0.0</code>) if there
314      * is no default property with the given name, or if the default
315      * value cannot be treated as a double.
316      *
317      * @param name the name of the property
318      * @return the default value of the named property
319      */

320     public double getDefaultDouble(String JavaDoc name) {
321         return getDefaultPreferences().getDouble(name, DOUBLE_DEFAULT_DEFAULT);
322     }
323
324     /**
325      * Sets the default value for the double-valued property with the
326      * given name.
327      * <p>
328      * Note that the current value of the property is affected if
329      * the property's current value was its old default value, in which
330      * case it changes to the new default value. If the property's current
331      * is different from its old default value, its current value is
332      * unaffected. No property change events are reported by changing default
333      * values.
334      * </p>
335      *
336      * @param name the name of the property
337      * @param value the new default value for the property; must be
338      * a number (not a NaN)
339      */

340     public void setDefault(String JavaDoc name, double value) {
341         if (Double.isNaN(value))
342             throw new IllegalArgumentException JavaDoc();
343         getDefaultPreferences().putDouble(name, value);
344     }
345
346     /**
347      * Returns the current value of the float-valued property with the
348      * given name.
349      * Returns the default-default value (<code>0.0f</code>) if there
350      * is no property with the given name, or if the current value
351      * cannot be treated as a float.
352      *
353      * @param name the name of the property
354      * @return the float-valued property
355      */

356     public float getFloat(String JavaDoc name) {
357         return getPluginPreferences(true).getFloat(name, getDefaultPreferences().getFloat(name, FLOAT_DEFAULT_DEFAULT));
358     }
359
360     /**
361      * Sets the current value of the float-valued property with the
362      * given name.
363      * <p>
364      * A property change event is reported if the current value of the
365      * property actually changes from its previous value. In the event
366      * object, the property name is the name of the property, and the
367      * old and new values are wrapped as objects.
368      * </p>
369      * <p>
370      * If the given value is the same as the corresponding default value
371      * for the given property, the explicit setting is deleted.
372      * Note that the recommended way of re-initializing a property to its
373      * default value is to call <code>setToDefault</code>.
374      * </p>
375      *
376      * @param name the name of the property
377      * @param value the new current value of the property; must be
378      * a number (not a NaN)
379      */

380     public void setValue(String JavaDoc name, float value) {
381         if (Float.isNaN(value))
382             throw new IllegalArgumentException JavaDoc();
383         final float floatValue = getFloat(name);
384         if (value == floatValue)
385             return;
386         Float JavaDoc oldValue = new Float JavaDoc(floatValue);
387         Float JavaDoc newValue = new Float JavaDoc(value);
388         try {
389             notify = false;
390             if (getDefaultFloat(name) == value)
391                 getPluginPreferences(true).remove(name);
392             else
393                 getPluginPreferences(true).putFloat(name, value);
394             firePropertyChangeEvent(name, oldValue, newValue);
395         } finally {
396             notify = true;
397         }
398     }
399
400     /**
401      * Returns the default value for the float-valued property
402      * with the given name.
403      * Returns the default-default value (<code>0.0f</code>) if there
404      * is no default property with the given name, or if the default
405      * value cannot be treated as a float.
406      *
407      * @param name the name of the property
408      * @return the default value of the named property
409      */

410     public float getDefaultFloat(String JavaDoc name) {
411         return getDefaultPreferences().getFloat(name, FLOAT_DEFAULT_DEFAULT);
412     }
413
414     /**
415      * Sets the default value for the float-valued property with the
416      * given name.
417      * <p>
418      * Note that the current value of the property is affected if
419      * the property's current value was its old default value, in which
420      * case it changes to the new default value. If the property's current
421      * is different from its old default value, its current value is
422      * unaffected. No property change events are reported by changing default
423      * values.
424      * </p>
425      *
426      * @param name the name of the property
427      * @param value the new default value for the property; must be
428      * a number (not a NaN)
429      */

430     public void setDefault(String JavaDoc name, float value) {
431         if (Float.isNaN(value))
432             throw new IllegalArgumentException JavaDoc();
433         getDefaultPreferences().putFloat(name, value);
434     }
435
436     /**
437      * Returns the current value of the integer-valued property with the
438      * given name.
439      * Returns the default-default value (<code>0</code>) if there
440      * is no property with the given name, or if the current value
441      * cannot be treated as an integter.
442      *
443      * @param name the name of the property
444      * @return the int-valued property
445      */

446     public int getInt(String JavaDoc name) {
447         return getPluginPreferences(true).getInt(name, getDefaultPreferences().getInt(name, INT_DEFAULT_DEFAULT));
448     }
449
450     /**
451      * Sets the current value of the integer-valued property with the
452      * given name.
453      * <p>
454      * A property change event is reported if the current value of the
455      * property actually changes from its previous value. In the event
456      * object, the property name is the name of the property, and the
457      * old and new values are wrapped as objects.
458      * </p>
459      * <p>
460      * If the given value is the same as the corresponding default value
461      * for the given property, the explicit setting is deleted.
462      * Note that the recommended way of re-initializing a property to its
463      * default value is to call <code>setToDefault</code>.
464      * </p>
465      *
466      * @param name the name of the property
467      * @param value the new current value of the property
468      */

469     public void setValue(String JavaDoc name, int value) {
470         final int intValue = getInt(name);
471         if (value == intValue)
472             return;
473         Integer JavaDoc oldValue = new Integer JavaDoc(intValue);
474         Integer JavaDoc newValue = new Integer JavaDoc(value);
475         try {
476             notify = false;
477             if (getDefaultInt(name) == value)
478                 getPluginPreferences(true).remove(name);
479             else
480                 getPluginPreferences(true).putInt(name, value);
481             firePropertyChangeEvent(name, oldValue, newValue);
482         } finally {
483             notify = true;
484         }
485     }
486
487     /**
488      * Returns the default value for the integer-valued property
489      * with the given name.
490      * Returns the default-default value (<code>0</code>) if there
491      * is no default property with the given name, or if the default
492      * value cannot be treated as an integer.
493      *
494      * @param name the name of the property
495      * @return the default value of the named property
496      */

497     public int getDefaultInt(String JavaDoc name) {
498         return getDefaultPreferences().getInt(name, INT_DEFAULT_DEFAULT);
499     }
500
501     /**
502      * Sets the default value for the integer-valued property with the
503      * given name.
504      * <p>
505      * Note that the current value of the property is affected if
506      * the property's current value was its old default value, in which
507      * case it changes to the new default value. If the property's current
508      * is different from its old default value, its current value is
509      * unaffected. No property change events are reported by changing default
510      * values.
511      * </p>
512      *
513      * @param name the name of the property
514      * @param value the new default value for the property
515      */

516     public void setDefault(String JavaDoc name, int value) {
517         getDefaultPreferences().putInt(name, value);
518     }
519
520     /**
521      * Returns the current value of the long-valued property with the
522      * given name.
523      * Returns the default-default value (<code>0L</code>) if there
524      * is no property with the given name, or if the current value
525      * cannot be treated as a long.
526      *
527      * @param name the name of the property
528      * @return the long-valued property
529      */

530     public long getLong(String JavaDoc name) {
531         return getPluginPreferences(true).getLong(name, getDefaultPreferences().getLong(name, LONG_DEFAULT_DEFAULT));
532     }
533
534     /**
535      * Sets the current value of the long-valued property with the
536      * given name.
537      * <p>
538      * A property change event is reported if the current value of the
539      * property actually changes from its previous value. In the event
540      * object, the property name is the name of the property, and the
541      * old and new values are wrapped as objects.
542      * </p>
543      * <p>
544      * If the given value is the same as the corresponding default value
545      * for the given property, the explicit setting is deleted.
546      * Note that the recommended way of re-initializing a property to its
547      * default value is to call <code>setToDefault</code>.
548      * </p>
549      *
550      * @param name the name of the property
551      * @param value the new current value of the property
552      */

553     public void setValue(String JavaDoc name, long value) {
554         final long longValue = getLong(name);
555         if (value == longValue)
556             return;
557         Long JavaDoc oldValue = new Long JavaDoc(longValue);
558         Long JavaDoc newValue = new Long JavaDoc(value);
559         try {
560             notify = false;
561             if (getDefaultLong(name) == value)
562                 getPluginPreferences(true).remove(name);
563             else
564                 getPluginPreferences(true).putLong(name, value);
565             firePropertyChangeEvent(name, oldValue, newValue);
566         } finally {
567             notify = true;
568         }
569     }
570
571     /**
572      * Returns the default value for the long-valued property
573      * with the given name.
574      * Returns the default-default value (<code>0L</code>) if there
575      * is no default property with the given name, or if the default
576      * value cannot be treated as a long.
577      *
578      * @param name the name of the property
579      * @return the default value of the named property
580      */

581     public long getDefaultLong(String JavaDoc name) {
582         return getDefaultPreferences().getLong(name, LONG_DEFAULT_DEFAULT);
583     }
584
585     /**
586      * Sets the default value for the long-valued property with the
587      * given name.
588      * <p>
589      * Note that the current value of the property is affected if
590      * the property's current value was its old default value, in which
591      * case it changes to the new default value. If the property's current
592      * is different from its old default value, its current value is
593      * unaffected. No property change events are reported by changing default
594      * values.
595      * </p>
596      *
597      * @param name the name of the property
598      * @param value the new default value for the property
599      */

600     public void setDefault(String JavaDoc name, long value) {
601         getDefaultPreferences().putLong(name, value);
602     }
603
604     /**
605      * Returns the current value of the string-valued property with the
606      * given name.
607      * Returns the default-default value (the empty string <code>""</code>)
608      * if there is no property with the given name.
609      *
610      * @param name the name of the property
611      * @return the string-valued property
612      */

613     public String JavaDoc getString(String JavaDoc name) {
614         return getPluginPreferences(true).get(name, getDefaultPreferences().get(name, STRING_DEFAULT_DEFAULT));
615     }
616
617     /**
618      * Sets the current value of the string-valued property with the
619      * given name.
620      * <p>
621      * A property change event is reported if the current value of the
622      * property actually changes from its previous value. In the event
623      * object, the property name is the name of the property, and the
624      * old and new values are wrapped as objects.
625      * </p>
626      * <p>
627      * If the given value is the same as the corresponding default value
628      * for the given property, the explicit setting is deleted.
629      * Note that the recommended way of re-initializing a property to its
630      * default value is to call <code>setToDefault</code>.
631      * </p>
632      *
633      * @param name the name of the property
634      * @param value the new current value of the property
635      */

636     public void setValue(String JavaDoc name, String JavaDoc value) {
637         if (value == null)
638             throw new IllegalArgumentException JavaDoc();
639         String JavaDoc oldValue = getString(name);
640         if (value.equals(oldValue))
641             return;
642         try {
643             notify = false;
644             if (getDefaultString(name).equals(value))
645                 getPluginPreferences(true).remove(name);
646             else
647                 getPluginPreferences(true).put(name, value);
648             firePropertyChangeEvent(name, oldValue, value);
649         } finally {
650             notify = true;
651         }
652     }
653
654     /**
655      * Returns the default value for the string-valued property
656      * with the given name.
657      * Returns the default-default value (the empty string <code>""</code>)
658      * is no default property with the given name, or if the default
659      * value cannot be treated as a string.
660      *
661      * @param name the name of the property
662      * @return the default value of the named property
663      */

664     public String JavaDoc getDefaultString(String JavaDoc name) {
665         return getDefaultPreferences().get(name, STRING_DEFAULT_DEFAULT);
666     }
667
668     /**
669      * Sets the default value for the string-valued property with the
670      * given name.
671      * <p>
672      * Note that the current value of the property is affected if
673      * the property's current value was its old default value, in which
674      * case it changes to the new default value. If the property's current
675      * is different from its old default value, its current value is
676      * unaffected. No property change events are reported by changing default
677      * values.
678      * </p>
679      *
680      * @param name the name of the property
681      * @param value the new default value for the property
682      */

683     public void setDefault(String JavaDoc name, String JavaDoc value) {
684         if (value == null)
685             throw new IllegalArgumentException JavaDoc();
686         getDefaultPreferences().put(name, value);
687     }
688
689     /**
690      * Returns whether the property with the given name has the default value in
691      * virtue of having no explicitly set value.
692      *
693      * @param name the name of the property
694      * @return <code>true</code> if the property has no explicitly set value,
695      * and <code>false</code> otherwise (including the case where the property
696      * is unknown to this object)
697      */

698     public boolean isDefault(String JavaDoc name) {
699         if (name == null)
700             return false;
701         return getPluginPreferences(true).get(name, null) == null;
702     }
703
704     /**
705      * Sets the current value of the property with the given name back
706      * to its default value. Has no effect if the property does not have
707      * its own current value.
708      * <p>
709      * Note that the recommended way of re-initializing a property to the
710      * appropriate default value is to call <code>setToDefault</code>.
711      * This is implemented by removing the named value from the object,
712      * thereby exposing the default value.
713      * </p>
714      * <p>
715      * A property change event is always reported. In the event
716      * object, the property name is the name of the property, and the
717      * old and new values are either strings, or <code>null</code>
718      * indicating the default-default value.
719      * </p>
720      *
721      * @param name the name of the property
722      */

723     public void setToDefault(String JavaDoc name) {
724         IEclipsePreferences preferences = getPluginPreferences(true);
725         Object JavaDoc oldValue = preferences.get(name, null);
726         if (oldValue != null)
727             preferences.remove(name);
728     }
729
730     /**
731      * Returns a list of all properties known to this preference object which
732      * have current values other than their default value.
733      *
734      * @return an array of property names
735      */

736     public String JavaDoc[] propertyNames() {
737         return getPluginPreferences(true).keys();
738     }
739
740     /**
741      * Returns a list of all properties known to this preference object which
742      * have default values other than their default-default value.
743      *
744      * @return an array of property names
745      */

746     public String JavaDoc[] defaultPropertyNames() {
747         try {
748             return getDefaultPreferences().keys();
749         } catch (BackingStoreException e) {
750             logError(e.getMessage(), e);
751             return new String JavaDoc[0];
752         }
753     }
754
755     /**
756      * Returns whether the current values in this preference object
757      * require saving.
758      *
759      * @return <code>true</code> if at least one of the properties
760      * known to this preference object has a current value different from its
761      * default value, and <code>false</code> otherwise
762      */

763     public boolean needsSaving() {
764         return getPluginPreferences(true).dirty;
765     }
766
767     /**
768      * Flush the values of these plug-in preferences to disk.
769      *
770      * @throws BackingStoreException
771      */

772     public void flush() throws BackingStoreException {
773         IEclipsePreferences node = getPluginPreferences(false);
774         if (node != null)
775             node.flush();
776     }
777
778     /*
779      * Something bad happened so log it.
780      */

781     private void logError(String JavaDoc message, Exception JavaDoc e) {
782         IStatus status = new Status(IStatus.ERROR, Platform.PI_RUNTIME, IStatus.ERROR, message, e);
783         InternalPlatform.getDefault().log(status);
784     }
785
786     /*
787      * @see org.eclipse.core.runtime.Preferences#load(java.io.InputStream)
788      */

789     public void load(InputStream in) throws IOException {
790         Properties JavaDoc result = new Properties JavaDoc();
791         result.load(in);
792         convertFromProperties(result);
793         // We loaded the prefs from a non-default location so now
794
// store them to disk. This also clears the dirty flag
795
// and therefore sets the #needsSaving() state correctly.
796
try {
797             flush();
798         } catch (BackingStoreException e) {
799             throw new IOException(e.getMessage());
800         }
801     }
802
803     /*
804      * @see org.eclipse.core.runtime.Preferences#store(java.io.OutputStream, java.lang.String)
805      */

806     public void store(OutputStream out, String JavaDoc header) throws IOException {
807         Properties JavaDoc result = convertToProperties();
808         result.store(out, header);
809         // We stored the prefs to a non-default location but the spec
810
// says that the dirty state is cleared so we want to store
811
// them to disk at the default location as well.
812
try {
813             flush();
814         } catch (BackingStoreException e) {
815             throw new IOException(e.getMessage());
816         }
817     }
818
819     private void convertFromProperties(Properties JavaDoc props) {
820         IEclipsePreferences preferences = getPluginPreferences(true);
821         for (Iterator JavaDoc i = props.keySet().iterator(); i.hasNext();) {
822             String JavaDoc key = (String JavaDoc) i.next();
823             String JavaDoc value = props.getProperty(key);
824             if (value != null)
825                 preferences.put(key, value);
826         }
827     }
828
829     public String JavaDoc toString() {
830         return "PreferenceForwarder(" + pluginID + ")"; //$NON-NLS-1$ //$NON-NLS-2$
831
}
832
833     /*
834      * Convert the preferences in this node to a properties file
835      * suitable for persistence.
836      */

837     private Properties JavaDoc convertToProperties() {
838         Properties JavaDoc result = new Properties JavaDoc();
839         String JavaDoc[] keys = propertyNames();
840         for (int i = 0; i < keys.length; i++) {
841             String JavaDoc key = keys[i];
842             String JavaDoc value = getString(key);
843             if (!Preferences.STRING_DEFAULT_DEFAULT.equals(value))
844                 result.put(key, value);
845         }
846         return result;
847     }
848 }
849
Popular Tags