/projects/eclipse_SDK-3.7.1/plugins/org.eclipse.ui.editors.source_3.7.0.v20110517-0800/org/eclipse/ui/texteditor/ChainedPreferenceStore.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus · Java · 556 lines · 279 code · 66 blank · 211 comment · 85 complexity · 0d4a8848cd1d48cdeb7014906b5a4f22 MD5 · raw file

  1. /*******************************************************************************
  2. * Copyright (c) 2000, 2010 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. import java.util.ArrayList;
  13. import java.util.Iterator;
  14. import java.util.List;
  15. import org.eclipse.core.runtime.Assert;
  16. import org.eclipse.core.runtime.ListenerList;
  17. import org.eclipse.jface.preference.IPreferenceStore;
  18. import org.eclipse.jface.util.IPropertyChangeListener;
  19. import org.eclipse.jface.util.PropertyChangeEvent;
  20. /**
  21. * Preference store that composes multiple preference stores in a
  22. * chain and serves a preference value from the first preference store in the
  23. * chain that contains the preference.
  24. * <p>
  25. * This preference store is read-only i.e. write access
  26. * throws an {@link java.lang.UnsupportedOperationException}.</p>
  27. *
  28. * @since 3.0
  29. */
  30. public class ChainedPreferenceStore implements IPreferenceStore {
  31. /** Child preference stores. */
  32. private IPreferenceStore[] fPreferenceStores;
  33. /** Listeners on this chained preference store. */
  34. private ListenerList fClientListeners= new ListenerList(ListenerList.IDENTITY);
  35. /** Listeners on the child preference stores. */
  36. private List fChildListeners= new ArrayList();
  37. /**
  38. * Listener on the chained preference stores. Forwards only the events
  39. * that are visible to clients.
  40. */
  41. private class PropertyChangeListener implements IPropertyChangeListener {
  42. /** Preference store to listen too. */
  43. private IPreferenceStore fPreferenceStore;
  44. /**
  45. * Initialize with the given preference store.
  46. *
  47. * @param preferenceStore the preference store
  48. */
  49. public PropertyChangeListener(IPreferenceStore preferenceStore) {
  50. setPreferenceStore(preferenceStore);
  51. }
  52. /*
  53. * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
  54. */
  55. public void propertyChange(PropertyChangeEvent event) {
  56. IPreferenceStore childPreferenceStore= getPreferenceStore();
  57. handlePropertyChangeEvent(childPreferenceStore, event);
  58. }
  59. /**
  60. * Registers this listener on the preference store.
  61. */
  62. public void register() {
  63. getPreferenceStore().addPropertyChangeListener(this);
  64. }
  65. /**
  66. * Unregisters this listener from the preference store.
  67. */
  68. public void unregister() {
  69. getPreferenceStore().removePropertyChangeListener(this);
  70. }
  71. /**
  72. * Returns the preference store.
  73. *
  74. * @return the preference store
  75. */
  76. public IPreferenceStore getPreferenceStore() {
  77. return fPreferenceStore;
  78. }
  79. /**
  80. * Sets the preference store.
  81. *
  82. * @param preferenceStore the preference store to set
  83. */
  84. public void setPreferenceStore(IPreferenceStore preferenceStore) {
  85. fPreferenceStore= preferenceStore;
  86. }
  87. }
  88. /**
  89. * Sets the chained preference stores.
  90. *
  91. * @param preferenceStores the chained preference stores to set
  92. */
  93. public ChainedPreferenceStore(IPreferenceStore[] preferenceStores) {
  94. Assert.isTrue(preferenceStores != null && preferenceStores.length > 0);
  95. fPreferenceStores= new IPreferenceStore[preferenceStores.length];
  96. System.arraycopy(preferenceStores, 0, fPreferenceStores, 0, preferenceStores.length);
  97. // Create listeners
  98. for (int i= 0, length= fPreferenceStores.length; i < length; i++) {
  99. PropertyChangeListener listener= new PropertyChangeListener(fPreferenceStores[i]);
  100. fChildListeners.add(listener);
  101. }
  102. }
  103. /*
  104. * @see org.eclipse.jface.preference.IPreferenceStore#addPropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
  105. */
  106. public void addPropertyChangeListener(IPropertyChangeListener listener) {
  107. if (fClientListeners.size() == 0) {
  108. registerChildListeners();
  109. }
  110. fClientListeners.add(listener);
  111. }
  112. /*
  113. * @see org.eclipse.jface.preference.IPreferenceStore#removePropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
  114. */
  115. public void removePropertyChangeListener(IPropertyChangeListener listener) {
  116. fClientListeners.remove(listener);
  117. if (fClientListeners.size() == 0) {
  118. unregisterChildListeners();
  119. }
  120. }
  121. /*
  122. * @see org.eclipse.jface.preference.IPreferenceStore#contains(java.lang.String)
  123. */
  124. public boolean contains(String name) {
  125. return getVisibleStore(name) != null;
  126. }
  127. /*
  128. * @see org.eclipse.jface.preference.IPreferenceStore#firePropertyChangeEvent(java.lang.String, java.lang.Object, java.lang.Object)
  129. */
  130. public void firePropertyChangeEvent(String name, Object oldValue, Object newValue) {
  131. firePropertyChangeEvent(new PropertyChangeEvent(this, name, oldValue, newValue));
  132. }
  133. /**
  134. * Fire the given property change event.
  135. *
  136. * @param event the property change event
  137. */
  138. private void firePropertyChangeEvent(PropertyChangeEvent event) {
  139. Object[] listeners= fClientListeners.getListeners();
  140. for (int i= 0; i < listeners.length; i++)
  141. ((IPropertyChangeListener) listeners[i]).propertyChange(event);
  142. }
  143. /*
  144. * @see org.eclipse.jface.preference.IPreferenceStore#getBoolean(java.lang.String)
  145. */
  146. public boolean getBoolean(String name) {
  147. IPreferenceStore visibleStore= getVisibleStore(name);
  148. if (visibleStore != null)
  149. return visibleStore.getBoolean(name);
  150. return BOOLEAN_DEFAULT_DEFAULT;
  151. }
  152. /*
  153. * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultBoolean(java.lang.String)
  154. */
  155. public boolean getDefaultBoolean(String name) {
  156. IPreferenceStore visibleStore= getVisibleStore(name);
  157. if (visibleStore != null)
  158. return visibleStore.getDefaultBoolean(name);
  159. return BOOLEAN_DEFAULT_DEFAULT;
  160. }
  161. /*
  162. * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultDouble(java.lang.String)
  163. */
  164. public double getDefaultDouble(String name) {
  165. IPreferenceStore visibleStore= getVisibleStore(name);
  166. if (visibleStore != null)
  167. return visibleStore.getDefaultDouble(name);
  168. return DOUBLE_DEFAULT_DEFAULT;
  169. }
  170. /*
  171. * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultFloat(java.lang.String)
  172. */
  173. public float getDefaultFloat(String name) {
  174. IPreferenceStore visibleStore= getVisibleStore(name);
  175. if (visibleStore != null)
  176. return visibleStore.getDefaultFloat(name);
  177. return FLOAT_DEFAULT_DEFAULT;
  178. }
  179. /*
  180. * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultInt(java.lang.String)
  181. */
  182. public int getDefaultInt(String name) {
  183. IPreferenceStore visibleStore= getVisibleStore(name);
  184. if (visibleStore != null)
  185. return visibleStore.getDefaultInt(name);
  186. return INT_DEFAULT_DEFAULT;
  187. }
  188. /*
  189. * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultLong(java.lang.String)
  190. */
  191. public long getDefaultLong(String name) {
  192. IPreferenceStore visibleStore= getVisibleStore(name);
  193. if (visibleStore != null)
  194. return visibleStore.getDefaultLong(name);
  195. return LONG_DEFAULT_DEFAULT;
  196. }
  197. /*
  198. * @see org.eclipse.jface.preference.IPreferenceStore#getDefaultString(java.lang.String)
  199. */
  200. public String getDefaultString(String name) {
  201. IPreferenceStore visibleStore= getVisibleStore(name);
  202. if (visibleStore != null)
  203. return visibleStore.getDefaultString(name);
  204. return STRING_DEFAULT_DEFAULT;
  205. }
  206. /*
  207. * @see org.eclipse.jface.preference.IPreferenceStore#getDouble(java.lang.String)
  208. */
  209. public double getDouble(String name) {
  210. IPreferenceStore visibleStore= getVisibleStore(name);
  211. if (visibleStore != null)
  212. return visibleStore.getDouble(name);
  213. return DOUBLE_DEFAULT_DEFAULT;
  214. }
  215. /*
  216. * @see org.eclipse.jface.preference.IPreferenceStore#getFloat(java.lang.String)
  217. */
  218. public float getFloat(String name) {
  219. IPreferenceStore visibleStore= getVisibleStore(name);
  220. if (visibleStore != null)
  221. return visibleStore.getFloat(name);
  222. return FLOAT_DEFAULT_DEFAULT;
  223. }
  224. /*
  225. * @see org.eclipse.jface.preference.IPreferenceStore#getInt(java.lang.String)
  226. */
  227. public int getInt(String name) {
  228. IPreferenceStore visibleStore= getVisibleStore(name);
  229. if (visibleStore != null)
  230. return visibleStore.getInt(name);
  231. return INT_DEFAULT_DEFAULT;
  232. }
  233. /*
  234. * @see org.eclipse.jface.preference.IPreferenceStore#getLong(java.lang.String)
  235. */
  236. public long getLong(String name) {
  237. IPreferenceStore visibleStore= getVisibleStore(name);
  238. if (visibleStore != null)
  239. return visibleStore.getLong(name);
  240. return LONG_DEFAULT_DEFAULT;
  241. }
  242. /*
  243. * @see org.eclipse.jface.preference.IPreferenceStore#getString(java.lang.String)
  244. */
  245. public String getString(String name) {
  246. IPreferenceStore visibleStore= getVisibleStore(name);
  247. if (visibleStore != null)
  248. return visibleStore.getString(name);
  249. return STRING_DEFAULT_DEFAULT;
  250. }
  251. /*
  252. * @see org.eclipse.jface.preference.IPreferenceStore#isDefault(java.lang.String)
  253. */
  254. public boolean isDefault(String name) {
  255. IPreferenceStore visibleStore= getVisibleStore(name);
  256. if (visibleStore != null)
  257. return visibleStore.isDefault(name);
  258. return false;
  259. }
  260. /*
  261. * @see org.eclipse.jface.preference.IPreferenceStore#needsSaving()
  262. */
  263. public boolean needsSaving() {
  264. throw new UnsupportedOperationException();
  265. }
  266. /*
  267. * @see org.eclipse.jface.preference.IPreferenceStore#putValue(java.lang.String, java.lang.String)
  268. */
  269. public void putValue(String name, String value) {
  270. throw new UnsupportedOperationException();
  271. }
  272. /*
  273. * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String, double)
  274. */
  275. public void setDefault(String name, double value) {
  276. throw new UnsupportedOperationException();
  277. }
  278. /*
  279. * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String, float)
  280. */
  281. public void setDefault(String name, float value) {
  282. throw new UnsupportedOperationException();
  283. }
  284. /*
  285. * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String, int)
  286. */
  287. public void setDefault(String name, int value) {
  288. throw new UnsupportedOperationException();
  289. }
  290. /*
  291. * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String, long)
  292. */
  293. public void setDefault(String name, long value) {
  294. throw new UnsupportedOperationException();
  295. }
  296. /*
  297. * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String, java.lang.String)
  298. */
  299. public void setDefault(String name, String defaultObject) {
  300. throw new UnsupportedOperationException();
  301. }
  302. /*
  303. * @see org.eclipse.jface.preference.IPreferenceStore#setDefault(java.lang.String, boolean)
  304. */
  305. public void setDefault(String name, boolean value) {
  306. throw new UnsupportedOperationException();
  307. }
  308. /*
  309. * @see org.eclipse.jface.preference.IPreferenceStore#setToDefault(java.lang.String)
  310. */
  311. public void setToDefault(String name) {
  312. throw new UnsupportedOperationException();
  313. }
  314. /*
  315. * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String, double)
  316. */
  317. public void setValue(String name, double value) {
  318. throw new UnsupportedOperationException();
  319. }
  320. /*
  321. * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String, float)
  322. */
  323. public void setValue(String name, float value) {
  324. throw new UnsupportedOperationException();
  325. }
  326. /*
  327. * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String, int)
  328. */
  329. public void setValue(String name, int value) {
  330. throw new UnsupportedOperationException();
  331. }
  332. /*
  333. * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String, long)
  334. */
  335. public void setValue(String name, long value) {
  336. throw new UnsupportedOperationException();
  337. }
  338. /*
  339. * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String, java.lang.String)
  340. */
  341. public void setValue(String name, String value) {
  342. throw new UnsupportedOperationException();
  343. }
  344. /*
  345. * @see org.eclipse.jface.preference.IPreferenceStore#setValue(java.lang.String, boolean)
  346. */
  347. public void setValue(String name, boolean value) {
  348. throw new UnsupportedOperationException();
  349. }
  350. /**
  351. * Handle property change event from the child listener with the given child preference store.
  352. *
  353. * @param childPreferenceStore the child preference store
  354. * @param event the event
  355. */
  356. private void handlePropertyChangeEvent(IPreferenceStore childPreferenceStore, PropertyChangeEvent event) {
  357. String property= event.getProperty();
  358. Object oldValue= event.getOldValue();
  359. Object newValue= event.getNewValue();
  360. IPreferenceStore visibleStore= getVisibleStore(property);
  361. /*
  362. * Assume that the property is there but has no default value (its owner relies on the default-default value)
  363. * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=52827
  364. */
  365. if (visibleStore == null && newValue != null)
  366. visibleStore= childPreferenceStore;
  367. if (visibleStore == null) {
  368. // no visible store
  369. if (oldValue != null)
  370. // removal in child, last in chain -> removal in this chained preference store
  371. firePropertyChangeEvent(event);
  372. } else if (visibleStore == childPreferenceStore) {
  373. // event from visible store
  374. if (oldValue != null) {
  375. // change in child, visible store -> change in this chained preference store
  376. firePropertyChangeEvent(event);
  377. } else {
  378. // insertion in child
  379. IPreferenceStore oldVisibleStore= null;
  380. int i= 0;
  381. int length= fPreferenceStores.length;
  382. while (i < length && fPreferenceStores[i++] != visibleStore) {
  383. // do nothing
  384. }
  385. while (oldVisibleStore == null && i < length) {
  386. if (fPreferenceStores[i].contains(property))
  387. oldVisibleStore= fPreferenceStores[i];
  388. i++;
  389. }
  390. if (oldVisibleStore == null) {
  391. // insertion in child, first in chain -> insertion in this chained preference store
  392. firePropertyChangeEvent(event);
  393. } else {
  394. // insertion in child, not first in chain
  395. oldValue= getOtherValue(property, oldVisibleStore, newValue);
  396. if (!oldValue.equals(newValue))
  397. // insertion in child, different old value -> change in this chained preference store
  398. firePropertyChangeEvent(property, oldValue, newValue);
  399. // else: insertion in child, same old value -> no change in this chained preference store
  400. }
  401. }
  402. } else {
  403. // event from other than the visible store
  404. boolean eventBeforeVisibleStore= false;
  405. for (int i= 0, length= fPreferenceStores.length; i < length; i++) {
  406. IPreferenceStore store= fPreferenceStores[i];
  407. if (store == visibleStore)
  408. break;
  409. if (store == childPreferenceStore) {
  410. eventBeforeVisibleStore= true;
  411. break;
  412. }
  413. }
  414. if (eventBeforeVisibleStore) {
  415. // removal in child, before visible store
  416. /*
  417. * The original event's new value can be non-null (removed assertion).
  418. * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=69419
  419. */
  420. newValue= getOtherValue(property, visibleStore, oldValue);
  421. if (!newValue.equals(oldValue))
  422. // removal in child, before visible store, different old value -> change in this chained preference store
  423. firePropertyChangeEvent(property, oldValue, newValue);
  424. // else: removal in child, before visible store, same old value -> no change in this chained preference store
  425. }
  426. // else: event behind visible store -> no change in this chained preference store
  427. }
  428. }
  429. /**
  430. * Returns an object of the same dynamic type as <code>thisValue</code>, the returned object
  431. * encapsulates the value of the <code>property</code> from the preference <code>store</code>.
  432. *
  433. * @param property the name of the considered property
  434. * @param store the preference store
  435. * @param thisValue the given value
  436. * @return the other value
  437. */
  438. private Object getOtherValue(String property, IPreferenceStore store, Object thisValue) {
  439. if (thisValue instanceof Boolean)
  440. return store.getBoolean(property) ? Boolean.TRUE : Boolean.FALSE;
  441. else if (thisValue instanceof Double)
  442. return new Double(store.getDouble(property));
  443. else if (thisValue instanceof Float)
  444. return new Float(store.getFloat(property));
  445. else if (thisValue instanceof Integer)
  446. return new Integer(store.getInt(property));
  447. else if (thisValue instanceof Long)
  448. return new Long(store.getLong(property));
  449. else if (thisValue instanceof String)
  450. return store.getString(property);
  451. return store.getString(property);
  452. }
  453. /**
  454. * Returns the preference store from which the given property's value
  455. * is visible.
  456. *
  457. * @param property the name of the property
  458. * @return the preference store from which the property's value is visible,
  459. * <code>null</code> if the property is unknown
  460. */
  461. private IPreferenceStore getVisibleStore(String property) {
  462. IPreferenceStore visibleStore= null;
  463. for (int i= 0, length= fPreferenceStores.length; i < length && visibleStore == null; i++) {
  464. IPreferenceStore store= fPreferenceStores[i];
  465. if (store.contains(property))
  466. visibleStore= store;
  467. }
  468. return visibleStore;
  469. }
  470. /**
  471. * Register the child listeners on the child preference stores.
  472. */
  473. private void registerChildListeners() {
  474. Iterator iter= fChildListeners.iterator();
  475. while (iter.hasNext()) {
  476. PropertyChangeListener listener= (PropertyChangeListener) iter.next();
  477. listener.register();
  478. }
  479. }
  480. /**
  481. * Unregister the child listeners from the child preference stores.
  482. */
  483. private void unregisterChildListeners() {
  484. Iterator iter= fChildListeners.iterator();
  485. while (iter.hasNext()) {
  486. PropertyChangeListener listener= (PropertyChangeListener) iter.next();
  487. listener.unregister();
  488. }
  489. }
  490. }