KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > texteditor > ChainedPreferenceStore


1 /*******************************************************************************
2  * Copyright (c) 2000, 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 package org.eclipse.ui.texteditor;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.core.runtime.Assert;
18 import org.eclipse.core.runtime.ListenerList;
19
20 import org.eclipse.jface.preference.IPreferenceStore;
21 import org.eclipse.jface.util.IPropertyChangeListener;
22 import org.eclipse.jface.util.PropertyChangeEvent;
23
24
25 /**
26  * Preference store that composes multiple preference stores in a
27  * chain and serves a preference value from the first preference store in the
28  * chain that contains the preference.
29  * <p>
30  * This preference store is read-only i.e. write access
31  * throws an {@link java.lang.UnsupportedOperationException}.</p>
32  *
33  * @since 3.0
34  */

35 public class ChainedPreferenceStore implements IPreferenceStore {
36
37     /** Child preference stores. */
38     private IPreferenceStore[] fPreferenceStores;
39
40     /** Listeners on this chained preference store. */
41     private ListenerList fClientListeners= new ListenerList(ListenerList.IDENTITY);
42
43     /** Listeners on the child preference stores. */
44     private List JavaDoc fChildListeners= new ArrayList JavaDoc();
45
46     /**
47      * Listener on the chained preference stores. Forwards only the events
48      * that are visible to clients.
49      */

50     private class PropertyChangeListener implements IPropertyChangeListener {
51
52         /** Preference store to listen too. */
53         private IPreferenceStore fPreferenceStore;
54
55         /**
56          * Initialize with the given preference store.
57          *
58          * @param preferenceStore the preference store
59          */

60         public PropertyChangeListener(IPreferenceStore preferenceStore) {
61             setPreferenceStore(preferenceStore);
62         }
63
64         /*
65          * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
66          */

67         public void propertyChange(PropertyChangeEvent event) {
68             IPreferenceStore childPreferenceStore= getPreferenceStore();
69             handlePropertyChangeEvent(childPreferenceStore, event);
70         }
71
72         /**
73          * Registers this listener on the preference store.
74          */

75         public void register() {
76             getPreferenceStore().addPropertyChangeListener(this);
77         }
78
79         /**
80          * Unregisters this listener from the preference store.
81          */

82         public void unregister() {
83             getPreferenceStore().removePropertyChangeListener(this);
84         }
85
86         /**
87          * Returns the preference store.
88          *
89          * @return the preference store
90          */

91         public IPreferenceStore getPreferenceStore() {
92             return fPreferenceStore;
93         }
94
95         /**
96          * Sets the preference store.
97          *
98          * @param preferenceStore the preference store to set
99          */

100         public void setPreferenceStore(IPreferenceStore preferenceStore) {
101             fPreferenceStore= preferenceStore;
102         }
103
104     }
105
106     /**
107      * Sets the chained preference stores.
108      *
109      * @param preferenceStores the chained preference stores to set
110      */

111     public ChainedPreferenceStore(IPreferenceStore[] preferenceStores) {
112         Assert.isTrue(preferenceStores != null && preferenceStores.length > 0);
113         fPreferenceStores= new IPreferenceStore[preferenceStores.length];
114         System.arraycopy(preferenceStores, 0, fPreferenceStores, 0, preferenceStores.length);
115         // Create listeners
116
for (int i= 0, length= fPreferenceStores.length; i < length; i++) {
117             PropertyChangeListener listener= new PropertyChangeListener(fPreferenceStores[i]);
118             fChildListeners.add(listener);
119         }
120     }
121
122     /*
123      * @see org.eclipse.jface.preference.IPreferenceStore#addPropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
124      */

125     public void addPropertyChangeListener(IPropertyChangeListener listener) {
126         if (fClientListeners.size() == 0) {
127             registerChildListeners();
128         }
129         fClientListeners.add(listener);
130     }
131
132     /*
133      * @see org.eclipse.jface.preference.IPreferenceStore#removePropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
134      */

135     public void removePropertyChangeListener(IPropertyChangeListener listener) {
136         fClientListeners.remove(listener);
137         if (fClientListeners.size() == 0) {
138             unregisterChildListeners();
139         }
140     }
141
142     /*
143      * @see org.eclipse.jface.preference.IPreferenceStore#contains(java.lang.String)
144      */

145     public boolean contains(String JavaDoc name) {
146         return getVisibleStore(name) != null;
147     }
148
149     /*
150      * @see org.eclipse.jface.preference.IPreferenceStore#firePropertyChangeEvent(java.lang.String, java.lang.Object, java.lang.Object)
151      */

152     public void firePropertyChangeEvent(String JavaDoc name, Object JavaDoc oldValue, Object JavaDoc newValue) {
153         firePropertyChangeEvent(new PropertyChangeEvent(this, name, oldValue, newValue));
154     }
155
156     /**
157      * Fire the given property change event.
158      *
159      * @param event the property change event
160      */

161     private void firePropertyChangeEvent(PropertyChangeEvent event) {
162         Object JavaDoc[] listeners= fClientListeners.getListeners();
163         for (int i= 0; i < listeners.length; i++)
164              ((IPropertyChangeListener) listeners[i]).propertyChange(event);
165     }
166
167     /*
168      * @see org.eclipse.jface.preference.IPreferenceStore#getBoolean(java.lang.String)
169      */

170     public boolean getBoolean(String JavaDoc name) {
171         IPreferenceStore visibleStore= getVisibleStore(name);
172         if (visibleStore != null)
173             return visibleStore.getBoolean(name);
174         return BOOLEAN_DEFAULT_DEFAULT;
175     }
176
177     /*
178      * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultBoolean(java.lang.String)
179      */

180     public boolean getDefaultBoolean(String JavaDoc name) {
181         IPreferenceStore visibleStore= getVisibleStore(name);
182         if (visibleStore != null)
183             return visibleStore.getDefaultBoolean(name);
184         return BOOLEAN_DEFAULT_DEFAULT;
185     }
186
187     /*
188      * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultDouble(java.lang.String)
189      */

190     public double getDefaultDouble(String JavaDoc name) {
191         IPreferenceStore visibleStore= getVisibleStore(name);
192         if (visibleStore != null)
193             return visibleStore.getDefaultDouble(name);
194         return DOUBLE_DEFAULT_DEFAULT;
195     }
196
197     /*
198      * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultFloat(java.lang.String)
199      */

200     public float getDefaultFloat(String JavaDoc name) {
201         IPreferenceStore visibleStore= getVisibleStore(name);
202         if (visibleStore != null)
203             return visibleStore.getDefaultFloat(name);
204         return FLOAT_DEFAULT_DEFAULT;
205     }
206
207     /*
208      * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultInt(java.lang.String)
209      */

210     public int getDefaultInt(String JavaDoc name) {
211         IPreferenceStore visibleStore= getVisibleStore(name);
212         if (visibleStore != null)
213             return visibleStore.getDefaultInt(name);
214         return INT_DEFAULT_DEFAULT;
215     }
216
217     /*
218      * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultLong(java.lang.String)
219      */

220     public long getDefaultLong(String JavaDoc name) {
221         IPreferenceStore visibleStore= getVisibleStore(name);
222         if (visibleStore != null)
223             return visibleStore.getDefaultLong(name);
224         return LONG_DEFAULT_DEFAULT;
225     }
226
227     /*
228      * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultString(java.lang.String)
229      */

230     public String JavaDoc getDefaultString(String JavaDoc name) {
231         IPreferenceStore visibleStore= getVisibleStore(name);
232         if (visibleStore != null)
233             return visibleStore.getDefaultString(name);
234         return STRING_DEFAULT_DEFAULT;
235     }
236
237     /*
238      * @see org.eclipse.jface.preference.IPreferenceStore#getDouble(java.lang.String)
239      */

240     public double getDouble(String JavaDoc name) {
241         IPreferenceStore visibleStore= getVisibleStore(name);
242         if (visibleStore != null)
243             return visibleStore.getDouble(name);
244         return DOUBLE_DEFAULT_DEFAULT;
245     }
246
247     /*
248      * @see org.eclipse.jface.preference.IPreferenceStore#getFloat(java.lang.String)
249      */

250     public float getFloat(String JavaDoc name) {
251         IPreferenceStore visibleStore= getVisibleStore(name);
252         if (visibleStore != null)
253             return visibleStore.getFloat(name);
254         return FLOAT_DEFAULT_DEFAULT;
255     }
256
257     /*
258      * @see org.eclipse.jface.preference.IPreferenceStore#getInt(java.lang.String)
259      */

260     public int getInt(String JavaDoc name) {
261         IPreferenceStore visibleStore= getVisibleStore(name);
262         if (visibleStore != null)
263             return visibleStore.getInt(name);
264         return INT_DEFAULT_DEFAULT;
265     }
266
267     /*
268      * @see org.eclipse.jface.preference.IPreferenceStore#getLong(java.lang.String)
269      */

270     public long getLong(String JavaDoc name) {
271         IPreferenceStore visibleStore= getVisibleStore(name);
272         if (visibleStore != null)
273             return visibleStore.getLong(name);
274         return LONG_DEFAULT_DEFAULT;
275     }
276
277     /*
278      * @see org.eclipse.jface.preference.IPreferenceStore#getString(java.lang.String)
279      */

280     public String JavaDoc getString(String JavaDoc name) {
281         IPreferenceStore visibleStore= getVisibleStore(name);
282         if (visibleStore != null)
283             return visibleStore.getString(name);
284         return STRING_DEFAULT_DEFAULT;
285     }
286
287     /*
288      * @see org.eclipse.jface.preference.IPreferenceStore#isDefault(java.lang.String)
289      */

290     public boolean isDefault(String JavaDoc name) {
291         IPreferenceStore visibleStore= getVisibleStore(name);
292         if (visibleStore != null)
293             return visibleStore.isDefault(name);
294         return false;
295     }
296
297     /*
298      * @see org.eclipse.jface.preference.IPreferenceStore#needsSaving()
299      */

300     public boolean needsSaving() {
301         throw new UnsupportedOperationException JavaDoc();
302     }
303
304     /*
305      * @see org.eclipse.jface.preference.IPreferenceStore#putValue(java.lang.String, java.lang.String)
306      */

307     public void putValue(String JavaDoc name, String JavaDoc value) {
308         throw new UnsupportedOperationException JavaDoc();
309     }
310
311     /*
312      * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String, double)
313      */

314     public void setDefault(String JavaDoc name, double value) {
315         throw new UnsupportedOperationException JavaDoc();
316     }
317
318     /*
319      * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String, float)
320      */

321     public void setDefault(String JavaDoc name, float value) {
322         throw new UnsupportedOperationException JavaDoc();
323     }
324
325     /*
326      * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String, int)
327      */

328     public void setDefault(String JavaDoc name, int value) {
329         throw new UnsupportedOperationException JavaDoc();
330     }
331
332     /*
333      * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String, long)
334      */

335     public void setDefault(String JavaDoc name, long value) {
336         throw new UnsupportedOperationException JavaDoc();
337     }
338
339     /*
340      * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String, java.lang.String)
341      */

342     public void setDefault(String JavaDoc name, String JavaDoc defaultObject) {
343         throw new UnsupportedOperationException JavaDoc();
344     }
345
346     /*
347      * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String, boolean)
348      */

349     public void setDefault(String JavaDoc name, boolean value) {
350         throw new UnsupportedOperationException JavaDoc();
351     }
352
353     /*
354      * @see org.eclipse.jface.preference.IPreferenceStore#setToDefault(java.lang.String)
355      */

356     public void setToDefault(String JavaDoc name) {
357         throw new UnsupportedOperationException JavaDoc();
358     }
359
360     /*
361      * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String, double)
362      */

363     public void setValue(String JavaDoc name, double value) {
364         throw new UnsupportedOperationException JavaDoc();
365     }
366
367     /*
368      * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String, float)
369      */

370     public void setValue(String JavaDoc name, float value) {
371         throw new UnsupportedOperationException JavaDoc();
372     }
373
374     /*
375      * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String, int)
376      */

377     public void setValue(String JavaDoc name, int value) {
378         throw new UnsupportedOperationException JavaDoc();
379     }
380
381     /*
382      * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String, long)
383      */

384     public void setValue(String JavaDoc name, long value) {
385         throw new UnsupportedOperationException JavaDoc();
386     }
387
388     /*
389      * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String, java.lang.String)
390      */

391     public void setValue(String JavaDoc name, String JavaDoc value) {
392         throw new UnsupportedOperationException JavaDoc();
393     }
394
395     /*
396      * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String, boolean)
397      */

398     public void setValue(String JavaDoc name, boolean value) {
399         throw new UnsupportedOperationException JavaDoc();
400     }
401
402     /**
403      * Handle property change event from the child listener with the given child preference store.
404      *
405      * @param childPreferenceStore the child preference store
406      * @param event the event
407      */

408     private void handlePropertyChangeEvent(IPreferenceStore childPreferenceStore, PropertyChangeEvent event) {
409         String JavaDoc property= event.getProperty();
410         Object JavaDoc oldValue= event.getOldValue();
411         Object JavaDoc newValue= event.getNewValue();
412
413         IPreferenceStore visibleStore= getVisibleStore(property);
414
415         /*
416          * Assume that the property is there but has no default value (its owner relies on the default-default value)
417          * see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=52827
418          */

419         if (visibleStore == null && newValue != null)
420             visibleStore= childPreferenceStore;
421
422         if (visibleStore == null) {
423             // no visible store
424
if (oldValue != null)
425                 // removal in child, last in chain -> removal in this chained preference store
426
firePropertyChangeEvent(event);
427         } else if (visibleStore == childPreferenceStore) {
428             // event from visible store
429
if (oldValue != null) {
430                 // change in child, visible store -> change in this chained preference store
431
firePropertyChangeEvent(event);
432             } else {
433                 // insertion in child
434
IPreferenceStore oldVisibleStore= null;
435                 int i= 0;
436                 int length= fPreferenceStores.length;
437                 while (i < length && fPreferenceStores[i++] != visibleStore) {
438                     // do nothing
439
}
440                 while (oldVisibleStore == null && i < length) {
441                     if (fPreferenceStores[i].contains(property))
442                         oldVisibleStore= fPreferenceStores[i];
443                     i++;
444                 }
445
446                 if (oldVisibleStore == null) {
447                     // insertion in child, first in chain -> insertion in this chained preference store
448
firePropertyChangeEvent(event);
449                 } else {
450                     // insertion in child, not first in chain
451
oldValue= getOtherValue(property, oldVisibleStore, newValue);
452                     if (!oldValue.equals(newValue))
453                         // insertion in child, different old value -> change in this chained preference store
454
firePropertyChangeEvent(property, oldValue, newValue);
455                     // else: insertion in child, same old value -> no change in this chained preference store
456
}
457             }
458         } else {
459             // event from other than the visible store
460
boolean eventBeforeVisibleStore= false;
461             for (int i= 0, length= fPreferenceStores.length; i < length; i++) {
462                 IPreferenceStore store= fPreferenceStores[i];
463                 if (store == visibleStore)
464                     break;
465                 if (store == childPreferenceStore) {
466                     eventBeforeVisibleStore= true;
467                     break;
468                 }
469             }
470
471             if (eventBeforeVisibleStore) {
472                 // removal in child, before visible store
473

474                 /*
475                  * The original event's new value can be non-null (removed assertion).
476                  * see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=69419
477                  */

478
479                 newValue= getOtherValue(property, visibleStore, oldValue);
480                 if (!newValue.equals(oldValue))
481                     // removal in child, before visible store, different old value -> change in this chained preference store
482
firePropertyChangeEvent(property, oldValue, newValue);
483                 // else: removal in child, before visible store, same old value -> no change in this chained preference store
484
}
485             // else: event behind visible store -> no change in this chained preference store
486
}
487     }
488
489     /**
490      * Returns an object of the same dynamic type as <code>thisValue</code>, the returned object
491      * encapsulates the value of the <code>property</code> from the preference <code>store</code>.
492      *
493      * @param property the name of the considered property
494      * @param store the preference store
495      * @param thisValue the given value
496      * @return the other value
497      */

498     private Object JavaDoc getOtherValue(String JavaDoc property, IPreferenceStore store, Object JavaDoc thisValue) {
499
500         if (thisValue instanceof Boolean JavaDoc)
501             return store.getBoolean(property) ? Boolean.TRUE : Boolean.FALSE;
502         else if (thisValue instanceof Double JavaDoc)
503             return new Double JavaDoc(store.getDouble(property));
504         else if (thisValue instanceof Float JavaDoc)
505             return new Float JavaDoc(store.getFloat(property));
506         else if (thisValue instanceof Integer JavaDoc)
507             return new Integer JavaDoc(store.getInt(property));
508         else if (thisValue instanceof Long JavaDoc)
509             return new Long JavaDoc(store.getLong(property));
510         else if (thisValue instanceof String JavaDoc)
511             return store.getString(property);
512
513         return store.getString(property);
514     }
515
516     /**
517      * Returns the preference store from which the given property's value
518      * is visible.
519      *
520      * @param property the name of the property
521      * @return the preference store from which the property's value is visible,
522      * <code>null</code> if the property is unknown
523      */

524     private IPreferenceStore getVisibleStore(String JavaDoc property) {
525         IPreferenceStore visibleStore= null;
526
527         for (int i= 0, length= fPreferenceStores.length; i < length && visibleStore == null; i++) {
528             IPreferenceStore store= fPreferenceStores[i];
529             if (store.contains(property))
530                 visibleStore= store;
531         }
532         return visibleStore;
533     }
534
535     /**
536      * Register the child listeners on the child preference stores.
537      */

538     private void registerChildListeners() {
539         Iterator JavaDoc iter= fChildListeners.iterator();
540         while (iter.hasNext()) {
541             PropertyChangeListener listener= (PropertyChangeListener) iter.next();
542             listener.register();
543         }
544     }
545
546     /**
547      * Unregister the child listeners from the child preference stores.
548      */

549     private void unregisterChildListeners() {
550         Iterator JavaDoc iter= fChildListeners.iterator();
551         while (iter.hasNext()) {
552             PropertyChangeListener listener= (PropertyChangeListener) iter.next();
553             listener.unregister();
554         }
555     }
556 }
557
Popular Tags