1 /******************************************************************************* 2 * Copyright (c) 2000, 2008 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.ui.internal.editors.text; 15 16 import org.eclipse.core.runtime.Assert; 17 18 import org.eclipse.jface.preference.IPreferenceStore; 19 import org.eclipse.jface.preference.PreferenceStore; 20 import org.eclipse.jface.util.IPropertyChangeListener; 21 import org.eclipse.jface.util.PropertyChangeEvent; 22 23 24 /** 25 * An overlaying preference store. 26 * 27 * @since 2.1 28 */ 29 class OverlayPreferenceStore implements IPreferenceStore { 30 31 32 /** 33 * Descriptor used to denote data types. 34 */ 35 public static final class TypeDescriptor { TypeDescriptor()36 private TypeDescriptor() { 37 } 38 } 39 40 public static final TypeDescriptor BOOLEAN= new TypeDescriptor(); 41 public static final TypeDescriptor DOUBLE= new TypeDescriptor(); 42 public static final TypeDescriptor FLOAT= new TypeDescriptor(); 43 public static final TypeDescriptor INT= new TypeDescriptor(); 44 public static final TypeDescriptor LONG= new TypeDescriptor(); 45 public static final TypeDescriptor STRING= new TypeDescriptor(); 46 47 /** 48 * Data structure for the overlay key. 49 */ 50 public static class OverlayKey { 51 52 TypeDescriptor fDescriptor; 53 String fKey; 54 OverlayKey(TypeDescriptor descriptor, String key)55 public OverlayKey(TypeDescriptor descriptor, String key) { 56 fDescriptor= descriptor; 57 fKey= key; 58 } 59 } 60 61 /* 62 * @see IPropertyChangeListener 63 */ 64 private class PropertyListener implements IPropertyChangeListener { 65 66 @Override propertyChange(PropertyChangeEvent event)67 public void propertyChange(PropertyChangeEvent event) { 68 OverlayKey key= findOverlayKey(event.getProperty()); 69 if (key != null) 70 propagateProperty(fParent, key, fStore); 71 } 72 } 73 74 75 /** The parent preference store. */ 76 private IPreferenceStore fParent; 77 /** This store. */ 78 private IPreferenceStore fStore; 79 /** The keys of this store. */ 80 private OverlayKey[] fOverlayKeys; 81 /** The property listener. */ 82 private PropertyListener fPropertyListener; 83 private boolean fLoaded; 84 85 86 /** 87 * Creates and returns a new overlay preference store. 88 * 89 * @param parent the parent preference store 90 * @param overlayKeys the overlay keys 91 */ OverlayPreferenceStore(IPreferenceStore parent, OverlayKey[] overlayKeys)92 public OverlayPreferenceStore(IPreferenceStore parent, OverlayKey[] overlayKeys) { 93 fParent= parent; 94 fOverlayKeys= overlayKeys; 95 fStore= new PreferenceStore(); 96 } 97 98 /** 99 * Tries to find and return the overlay key for the given preference key string. 100 * 101 * @param key the preference key string 102 * @return the overlay key or <code>null</code> if none can be found 103 */ findOverlayKey(String key)104 private OverlayKey findOverlayKey(String key) { 105 for (OverlayKey fOverlayKey : fOverlayKeys) { 106 if (fOverlayKey.fKey.equals(key)) { 107 return fOverlayKey; 108 } 109 } 110 return null; 111 } 112 113 /** 114 * Tells whether the given preference key string is 115 * covered by this overlay store. 116 * 117 * @param key the preference key string 118 * @return <code>true</code> if this overlay store covers the given key 119 */ covers(String key)120 private boolean covers(String key) { 121 return (findOverlayKey(key) != null); 122 } 123 124 /** 125 * Propagates the given overlay key from the orgin to the target preference store. 126 * 127 * @param orgin the source preference store 128 * @param key the overlay key 129 * @param target the preference store to which the key is propagated 130 */ propagateProperty(IPreferenceStore orgin, OverlayKey key, IPreferenceStore target)131 private void propagateProperty(IPreferenceStore orgin, OverlayKey key, IPreferenceStore target) { 132 133 if (orgin.isDefault(key.fKey)) { 134 if (!target.isDefault(key.fKey)) 135 target.setToDefault(key.fKey); 136 return; 137 } 138 139 TypeDescriptor d= key.fDescriptor; 140 if (BOOLEAN == d) { 141 142 boolean originValue= orgin.getBoolean(key.fKey); 143 boolean targetValue= target.getBoolean(key.fKey); 144 if (targetValue != originValue) 145 target.setValue(key.fKey, originValue); 146 147 } else if (DOUBLE == d) { 148 149 double originValue= orgin.getDouble(key.fKey); 150 double targetValue= target.getDouble(key.fKey); 151 if (targetValue != originValue) 152 target.setValue(key.fKey, originValue); 153 154 } else if (FLOAT == d) { 155 156 float originValue= orgin.getFloat(key.fKey); 157 float targetValue= target.getFloat(key.fKey); 158 if (targetValue != originValue) 159 target.setValue(key.fKey, originValue); 160 161 } else if (INT == d) { 162 163 int originValue= orgin.getInt(key.fKey); 164 int targetValue= target.getInt(key.fKey); 165 if (targetValue != originValue) 166 target.setValue(key.fKey, originValue); 167 168 } else if (LONG == d) { 169 170 long originValue= orgin.getLong(key.fKey); 171 long targetValue= target.getLong(key.fKey); 172 if (targetValue != originValue) 173 target.setValue(key.fKey, originValue); 174 175 } else if (STRING == d) { 176 177 String originValue= orgin.getString(key.fKey); 178 String targetValue= target.getString(key.fKey); 179 if (targetValue != null && originValue != null && !targetValue.equals(originValue)) 180 target.setValue(key.fKey, originValue); 181 182 } 183 } 184 185 /** 186 * Propagates all overlay keys from this store to the parent store. 187 */ propagate()188 public void propagate() { 189 for (OverlayKey fOverlayKey : fOverlayKeys) { 190 propagateProperty(fStore, fOverlayKey, fParent); 191 } 192 } 193 194 /** 195 * Loads the given key from the orgin into the target. 196 * 197 * @param orgin the source preference store 198 * @param key the overlay key 199 * @param target the preference store to which the key is propagated 200 * @param forceInitialization if <code>true</code> the value in the target gets initialized before loading 201 */ loadProperty(IPreferenceStore orgin, OverlayKey key, IPreferenceStore target, boolean forceInitialization)202 private void loadProperty(IPreferenceStore orgin, OverlayKey key, IPreferenceStore target, boolean forceInitialization) { 203 TypeDescriptor d= key.fDescriptor; 204 if (BOOLEAN == d) { 205 206 if (forceInitialization) 207 target.setValue(key.fKey, true); 208 target.setValue(key.fKey, orgin.getBoolean(key.fKey)); 209 target.setDefault(key.fKey, orgin.getDefaultBoolean(key.fKey)); 210 211 } else if (DOUBLE == d) { 212 213 if (forceInitialization) 214 target.setValue(key.fKey, 1.0D); 215 target.setValue(key.fKey, orgin.getDouble(key.fKey)); 216 target.setDefault(key.fKey, orgin.getDefaultDouble(key.fKey)); 217 218 } else if (FLOAT == d) { 219 220 if (forceInitialization) 221 target.setValue(key.fKey, 1.0F); 222 target.setValue(key.fKey, orgin.getFloat(key.fKey)); 223 target.setDefault(key.fKey, orgin.getDefaultFloat(key.fKey)); 224 225 } else if (INT == d) { 226 227 if (forceInitialization) 228 target.setValue(key.fKey, 1); 229 target.setValue(key.fKey, orgin.getInt(key.fKey)); 230 target.setDefault(key.fKey, orgin.getDefaultInt(key.fKey)); 231 232 } else if (LONG == d) { 233 234 if (forceInitialization) 235 target.setValue(key.fKey, 1L); 236 target.setValue(key.fKey, orgin.getLong(key.fKey)); 237 target.setDefault(key.fKey, orgin.getDefaultLong(key.fKey)); 238 239 } else if (STRING == d) { 240 241 if (forceInitialization) 242 target.setValue(key.fKey, "1"); //$NON-NLS-1$ 243 target.setValue(key.fKey, orgin.getString(key.fKey)); 244 target.setDefault(key.fKey, orgin.getDefaultString(key.fKey)); 245 246 } 247 } 248 249 /** 250 * Loads the values from the parent into this store. 251 */ load()252 public void load() { 253 for (OverlayKey fOverlayKey : fOverlayKeys) { 254 loadProperty(fParent, fOverlayKey, fStore, true); 255 } 256 257 fLoaded= true; 258 } 259 260 /** 261 * Loads the default values. 262 */ loadDefaults()263 public void loadDefaults() { 264 for (OverlayKey fOverlayKey : fOverlayKeys) { 265 setToDefault(fOverlayKey.fKey); 266 } 267 } 268 269 /** 270 * Starts to listen for changes. 271 */ start()272 public void start() { 273 if (fPropertyListener == null) { 274 fPropertyListener= new PropertyListener(); 275 fParent.addPropertyChangeListener(fPropertyListener); 276 } 277 } 278 279 /** 280 * Stops to listen for changes. 281 */ stop()282 public void stop() { 283 if (fPropertyListener != null) { 284 fParent.removePropertyChangeListener(fPropertyListener); 285 fPropertyListener= null; 286 } 287 } 288 289 @Override addPropertyChangeListener(IPropertyChangeListener listener)290 public void addPropertyChangeListener(IPropertyChangeListener listener) { 291 fStore.addPropertyChangeListener(listener); 292 } 293 294 @Override removePropertyChangeListener(IPropertyChangeListener listener)295 public void removePropertyChangeListener(IPropertyChangeListener listener) { 296 fStore.removePropertyChangeListener(listener); 297 } 298 299 @Override firePropertyChangeEvent(String name, Object oldValue, Object newValue)300 public void firePropertyChangeEvent(String name, Object oldValue, Object newValue) { 301 fStore.firePropertyChangeEvent(name, oldValue, newValue); 302 } 303 304 @Override contains(String name)305 public boolean contains(String name) { 306 return fStore.contains(name); 307 } 308 309 @Override getBoolean(String name)310 public boolean getBoolean(String name) { 311 return fStore.getBoolean(name); 312 } 313 314 @Override getDefaultBoolean(String name)315 public boolean getDefaultBoolean(String name) { 316 return fStore.getDefaultBoolean(name); 317 } 318 319 @Override getDefaultDouble(String name)320 public double getDefaultDouble(String name) { 321 return fStore.getDefaultDouble(name); 322 } 323 324 @Override getDefaultFloat(String name)325 public float getDefaultFloat(String name) { 326 return fStore.getDefaultFloat(name); 327 } 328 329 @Override getDefaultInt(String name)330 public int getDefaultInt(String name) { 331 return fStore.getDefaultInt(name); 332 } 333 334 @Override getDefaultLong(String name)335 public long getDefaultLong(String name) { 336 return fStore.getDefaultLong(name); 337 } 338 339 @Override getDefaultString(String name)340 public String getDefaultString(String name) { 341 return fStore.getDefaultString(name); 342 } 343 344 @Override getDouble(String name)345 public double getDouble(String name) { 346 return fStore.getDouble(name); 347 } 348 349 @Override getFloat(String name)350 public float getFloat(String name) { 351 return fStore.getFloat(name); 352 } 353 354 @Override getInt(String name)355 public int getInt(String name) { 356 return fStore.getInt(name); 357 } 358 359 @Override getLong(String name)360 public long getLong(String name) { 361 return fStore.getLong(name); 362 } 363 364 @Override getString(String name)365 public String getString(String name) { 366 return fStore.getString(name); 367 } 368 369 @Override isDefault(String name)370 public boolean isDefault(String name) { 371 return fStore.isDefault(name); 372 } 373 374 @Override needsSaving()375 public boolean needsSaving() { 376 return fStore.needsSaving(); 377 } 378 379 @Override putValue(String name, String value)380 public void putValue(String name, String value) { 381 if (covers(name)) 382 fStore.putValue(name, value); 383 } 384 385 @Override setDefault(String name, double value)386 public void setDefault(String name, double value) { 387 if (covers(name)) 388 fStore.setDefault(name, value); 389 } 390 391 @Override setDefault(String name, float value)392 public void setDefault(String name, float value) { 393 if (covers(name)) 394 fStore.setDefault(name, value); 395 } 396 397 @Override setDefault(String name, int value)398 public void setDefault(String name, int value) { 399 if (covers(name)) 400 fStore.setDefault(name, value); 401 } 402 403 @Override setDefault(String name, long value)404 public void setDefault(String name, long value) { 405 if (covers(name)) 406 fStore.setDefault(name, value); 407 } 408 409 @Override setDefault(String name, String value)410 public void setDefault(String name, String value) { 411 if (covers(name)) 412 fStore.setDefault(name, value); 413 } 414 415 @Override setDefault(String name, boolean value)416 public void setDefault(String name, boolean value) { 417 if (covers(name)) 418 fStore.setDefault(name, value); 419 } 420 421 @Override setToDefault(String name)422 public void setToDefault(String name) { 423 fStore.setToDefault(name); 424 } 425 426 @Override setValue(String name, double value)427 public void setValue(String name, double value) { 428 if (covers(name)) 429 fStore.setValue(name, value); 430 } 431 432 @Override setValue(String name, float value)433 public void setValue(String name, float value) { 434 if (covers(name)) 435 fStore.setValue(name, value); 436 } 437 438 @Override setValue(String name, int value)439 public void setValue(String name, int value) { 440 if (covers(name)) 441 fStore.setValue(name, value); 442 } 443 444 @Override setValue(String name, long value)445 public void setValue(String name, long value) { 446 if (covers(name)) 447 fStore.setValue(name, value); 448 } 449 450 @Override setValue(String name, String value)451 public void setValue(String name, String value) { 452 if (covers(name)) 453 fStore.setValue(name, value); 454 } 455 456 @Override setValue(String name, boolean value)457 public void setValue(String name, boolean value) { 458 if (covers(name)) 459 fStore.setValue(name, value); 460 } 461 462 /** 463 * The keys to add to the list of overlay keys. 464 * <p> 465 * Note: This method must be called before {@link #load()} is called. 466 * </p> 467 * 468 * @param keys an array with overlay keys 469 * @since 3.0 470 */ addKeys(OverlayKey[] keys)471 public void addKeys(OverlayKey[] keys) { 472 Assert.isTrue(!fLoaded); 473 Assert.isNotNull(keys); 474 475 int overlayKeysLength= fOverlayKeys.length; 476 OverlayKey[] result= new OverlayKey[keys.length + overlayKeysLength]; 477 478 for (int i= 0, length= overlayKeysLength; i < length; i++) 479 result[i]= fOverlayKeys[i]; 480 481 for (int i= 0, length= keys.length; i < length; i++) 482 result[overlayKeysLength + i]= keys[i]; 483 484 fOverlayKeys= result; 485 486 if (fLoaded) 487 load(); 488 } 489 } 490