1 /*******************************************************************************
2  * Copyright (c) 2009, 2013 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.pde.internal.core;
15 
16 import org.eclipse.core.runtime.preferences.DefaultScope;
17 import org.eclipse.core.runtime.preferences.IEclipsePreferences;
18 import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
19 import org.eclipse.core.runtime.preferences.InstanceScope;
20 import org.osgi.service.prefs.BackingStoreException;
21 
22 /**
23  * Provides old {@link org.eclipse.core.runtime.Preferences} like interface to preferences but uses {@link IEclipsePreferences} instead
24  *
25  */
26 public final class PDEPreferencesManager {
27 
28 	private static final String EMPTY_STRING = ""; //$NON-NLS-1$
29 
30 	private final IEclipsePreferences fDefaultScopePrefs;
31 	private final IEclipsePreferences fInstanceScopePrefs;
32 
33 	/**
34 	 * Creates the preferences manager for the scope defined by ID
35 	 * @param ID scope for the preferences
36 	 */
PDEPreferencesManager(String ID)37 	public PDEPreferencesManager(String ID) {
38 		fInstanceScopePrefs = InstanceScope.INSTANCE.getNode(ID);
39 		fDefaultScopePrefs = DefaultScope.INSTANCE.getNode(ID);
40 	}
41 
42 	/**
43 	 * Register the given listener for notification of preference changes.
44 	 * Calling this method multiple times with the same listener has no effect. The
45 	 * given listener argument must not be <code>null</code>.
46 	 *
47 	 * @param listener the preference change listener to register
48 	 * @see #removePreferenceChangeListener(IEclipsePreferences.IPreferenceChangeListener)
49 	 * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener
50 	 */
addPreferenceChangeListener(IPreferenceChangeListener listener)51 	public void addPreferenceChangeListener(IPreferenceChangeListener listener) {
52 		fInstanceScopePrefs.addPreferenceChangeListener(listener);
53 	}
54 
55 	/**
56 	 * Returns the <code>boolean</code> value  associated with the specified <code>key</code>
57 	 * in the instance scope.
58 	 *
59 	 * <p>
60 	 * Returns the value specified in the default scope if there is no value associated with the
61 	 * <code>key</code> in the instance scope, the backing store is inaccessible, or if the associated
62 	 * value is something other than "true" or "false", ignoring case. Use {@link #setValue(String, boolean)}
63 	 * to set the value of this preference key.
64 	 * </p>
65 	 *
66 	 * @param key <code>key</code> whose associated value is to be returned as a
67 	 *        <code>boolean</code>.
68 	 * @return the <code>boolean</code> value associated with <code>key</code>, or
69 	 *         <code>false</code> if the associated value does not exist in either scope or cannot
70 	 *         be interpreted as a <code>boolean</code>.
71 	 * @see #setValue(String, boolean)
72 	 * @see #setValueOrRemove(String, boolean)
73 	 * @see #setDefault(String, boolean)
74 	 */
getBoolean(String key)75 	public boolean getBoolean(String key) {
76 		return fInstanceScopePrefs.getBoolean(key, fDefaultScopePrefs.getBoolean(key, false));
77 	}
78 
79 	/**
80 	 * Returns the <code>boolean</code> value associated with the specified <code>key</code>
81 	 * in the default scope.
82 	 *
83 	 * <p>
84 	 * Returns <code>false</code> if there is no value associated with the
85 	 * <code>key</code> in the default scope, the backing store is inaccessible, or if the associated
86 	 * value is something other than "true" or "false", ignoring case. Use {@link #setDefault(String, boolean)}
87 	 * to set the default value of this preference key.
88 	 * </p>
89 	 *
90 	 * @param key <code>key</code> whose associated value is to be returned as a
91 	 *        <code>boolean</code>.
92 	 * @return the <code>boolean</code> value associated with <code>key</code>, or
93 	 *         <code>false</code> if the associated value does not exist in default scope or cannot
94 	 *         be interpreted as a <code>boolean</code>.
95 	 * @see #setDefault(String, boolean)
96 	 */
getDefaultBoolean(String key)97 	public boolean getDefaultBoolean(String key) {
98 		return fDefaultScopePrefs.getBoolean(key, false);
99 	}
100 
101 	/**
102 	 * Returns the <code>int</code> value associated with the specified <code>key</code>
103 	 * in the default scope.
104 	 *
105 	 * <p>
106 	 * Returns <code>0</code> if there is no value associated with the
107 	 * <code>key</code> in the default scope, the backing store is inaccessible, or if the associated
108 	 * value is something that can not be parsed as an integer value. Use {@link #setDefault(String, int)}
109 	 * to set the default value of this preference key.
110 	 * </p>
111 	 *
112 	 * @param key <code>key</code> whose associated value is to be returned as a
113 	 *        <code>int</code>.
114 	 * @return the <code>int</code> value associated with <code>key</code>, or
115 	 *         <code>0</code> if the associated value does not exist in default scope or cannot
116 	 *         be interpreted as a <code>int</code>.
117 	 * @see #setDefault(String, int)
118 	 */
getDefaultInt(String key)119 	public int getDefaultInt(String key) {
120 		return fDefaultScopePrefs.getInt(key, 0);
121 	}
122 
123 	/**
124 	 * Returns the value associated with the specified <code>key</code>
125 	 * in the default scope.
126 	 *
127 	 * <p>
128 	 * Returns empty string <code>""</code> if there is no value associated with the
129 	 * <code>key</code> in the default scope, the backing store is inaccessible, or if the associated
130 	 * value is something that can not be parsed as an integer value. Use {@link #setDefault(String, String)}
131 	 * to set the default value of this preference key.
132 	 * </p>
133 	 *
134 	 * @param key <code>key</code> whose associated value is to be returned.
135 	 * @return the value associated with <code>key</code>, or
136 	 *         empty string <code>""</code> if the associated value does not exist in default scope.
137 	 * @see #setDefault(String, String)
138 	 */
getDefaultString(String key)139 	public String getDefaultString(String key) {
140 		return fDefaultScopePrefs.get(key, EMPTY_STRING);
141 	}
142 
143 	/**
144 	 * Returns the <code>int</code> value associated with the specified <code>key</code>
145 	 * in the instance scope.
146 	 *
147 	 * <p>
148 	 * Returns the value specified in the default scope if there is no value associated with the
149 	 * <code>key</code> in the instance scope, the backing store is inaccessible, or if the associated
150 	 * value is something that can not be parsed as an integer value. Use {@link #setValue(String, int)}
151 	 * to set the value of this preference key.
152 	 * </p>
153 	 *
154 	 * @param key key whose associated value is to be returned as an <code>int</code>.
155 	 * @return the <code>int</code> value associated with <code>key</code>, or
156 	 *         <code>0</code> if the associated value does not exist in either scope or cannot
157 	 *         be interpreted as an <code>int</code>.
158 	 * @see #setValue(String, int)
159 	 * @see #setValueOrRemove(String, int)
160 	 * @see #setDefault(String, int)
161 	 */
getInt(String key)162 	public int getInt(String key) {
163 		return fInstanceScopePrefs.getInt(key, fDefaultScopePrefs.getInt(key, 0));
164 	}
165 
166 	/**
167 	 * Returns the value associated with the specified <code>key</code> in the instance scope.
168 	 *
169 	 * <p>
170 	 * Returns the value specified in the default scope if there is no value associated with the
171 	 * <code>key</code> in the instance scope, the backing store is inaccessible. Use {@link #setValue(String, String)}
172 	 * to set the value of this preference key.
173 	 * </p>
174 	 *
175 	 * @param key key whose associated value is to be returned.
176 	 * @return the value associated with <code>key</code>, or
177 	 *         <code>null</code> if the associated value does not exist in either scope.
178 	 * @see #setValue(String, String)
179 	 * @see #setValueOrRemove(String, String)
180 	 * @see #setDefault(String, String)
181 	 */
getString(String key)182 	public String getString(String key) {
183 		return fInstanceScopePrefs.get(key, fDefaultScopePrefs.get(key, EMPTY_STRING));
184 	}
185 
186 	/**
187 	 * De-register the given listener from receiving notification of preference changes
188 	 * Calling this method multiple times with the same listener has no
189 	 * effect. The given listener argument must not be <code>null</code>.
190 	 *
191 	 * @param listener the preference change listener to remove
192 	 * @see #addPreferenceChangeListener(IEclipsePreferences.IPreferenceChangeListener)
193 	 * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener
194 	 */
removePreferenceChangeListener(IPreferenceChangeListener listener)195 	public void removePreferenceChangeListener(IPreferenceChangeListener listener) {
196 		fInstanceScopePrefs.removePreferenceChangeListener(listener);
197 	}
198 
199 	/**
200 	 * Forces any changes in the preferences to the persistent store.
201 	 */
savePluginPreferences()202 	public void savePluginPreferences() {
203 		try {
204 			fInstanceScopePrefs.flush();
205 		} catch (BackingStoreException e) {
206 			PDECore.logException(e);
207 		}
208 	}
209 
210 	/**
211 	 * Associates the specified <code>boolean</code> value with the specified key in the default scope.
212 	 * This method is intended for use in conjunction with the {@link #getDefaultBoolean(String)} method.
213 	 *
214 	 * @param key <code>key</code> with which the string form of value is to be associated.
215 	 * @param value <code>value</code> to be associated with <code>key</code>.
216 	 * @see #getDefaultBoolean(String)
217 	 * @see #getBoolean(String)
218 	 */
setDefault(String key, boolean value)219 	public void setDefault(String key, boolean value) {
220 		fDefaultScopePrefs.putBoolean(key, value);
221 	}
222 
223 	/**
224 	 * Associates the specified <code>int</code> value with the specified key in the default scope.
225 	 * This method is intended for use in conjunction with the {@link #getDefaultInt(String)} method.
226 	 *
227 	 * @param key <code>key</code> with which the string form of value is to be associated.
228 	 * @param value <code>value</code> to be associated with <code>key</code>.
229 	 * @see #getDefaultInt(String)
230 	 * @see #getInt(String)
231 	 */
setDefault(String key, int value)232 	public void setDefault(String key, int value) {
233 		fDefaultScopePrefs.putInt(key, value);
234 	}
235 
236 	/**
237 	 * Associates the specified <code>String</code> value with the specified key in the default scope.
238 	 * This method is intended for use in conjunction with the {@link #getDefaultString(String)} method.
239 	 *
240 	 * @param key <code>key</code> with which the string form of value is to be associated.
241 	 * @param value <code>value</code> to be associated with <code>key</code>.
242 	 * @see #getDefaultString(String)
243 	 * @see #getString(String)
244 	 */
setDefault(String key, String value)245 	public void setDefault(String key, String value) {
246 		fDefaultScopePrefs.put(key, value);
247 	}
248 
249 	/**
250 	 * Sets the current value of the preference with the given name back to its default value.
251 	 * The given name must not be <code>null</code>.
252 	 *
253 	 * @param key the name of the preference
254 	 */
setToDefault(String key)255 	public void setToDefault(String key) {
256 		fInstanceScopePrefs.put(key, fDefaultScopePrefs.get(key, EMPTY_STRING));
257 	}
258 
259 	/**
260 	 * Associates the specified <code>boolean</code> value with the specified key in the instance scope.
261 	 * This method is intended for use in conjunction with the {@link #getBoolean(String)} method.
262 	 *
263 	 * @param key <code>key</code> with which the <code>boolean</code> value is to be associated.
264 	 * @param value <code>value</code> to be associated with <code>key</code>.
265 	 * @see #getBoolean(String)
266 	 * @see #getDefaultBoolean(String)
267 	 * @see #setToDefault(String)
268 	 */
setValue(String key, boolean value)269 	public void setValue(String key, boolean value) {
270 		fInstanceScopePrefs.putBoolean(key, value);
271 	}
272 
273 	/**
274 	 * Associates the specified <code>int</code> value with the specified key in the instance scope.
275 	 * This method is intended for use in conjunction with the {@link #getInt(String)} method.
276 	 *
277 	 * @param key <code>key</code> with which the <code>int</code> value is to be associated.
278 	 * @param value <code>value</code> to be associated with <code>key</code>.
279 	 * @see #getInt(String)
280 	 * @see #getDefaultInt(String)
281 	 * @see #setToDefault(String)
282 	 */
setValue(String key, int value)283 	public void setValue(String key, int value) {
284 		fInstanceScopePrefs.putInt(key, value);
285 	}
286 
287 	/**
288 	 * Associates the specified <code>String</code> value with the specified key in the instance scope.
289 	 * This method is intended for use in conjunction with the {@link #getString(String)} method.
290 	 *
291 	 * @param key <code>key</code> with which the <code>String</code> value is to be associated.
292 	 * @param value <code>value</code> to be associated with <code>key</code>.
293 	 * @see #getString(String)
294 	 * @see #getDefaultString(String)
295 	 * @see #setToDefault(String)
296 	 */
setValue(String key, String value)297 	public void setValue(String key, String value) {
298 		fInstanceScopePrefs.put(key, value);
299 	}
300 
301 	/**
302 	 * Associates the specified <code>boolean</code> value with the specified key in the instance scope
303 	 * or removes the preference if the value is equal to the value in the default scope.
304 	 * <p>
305 	 * This method is intended for use in conjunction with the {@link #getBoolean(String)} method.
306 	 *
307 	 * @param key <code>key</code> with which the <code>boolean</code> value is to be associated
308 	 * @param value <code>value</code> to be associated with <code>key</code>
309 	 * @see #getBoolean(String)
310 	 * @see #getDefaultBoolean(String)
311 	 * @see #setToDefault(String)
312 	 */
setValueOrRemove(String key, boolean value)313 	public void setValueOrRemove(String key, boolean value) {
314 		if (value == getDefaultBoolean(key)) {
315 			fInstanceScopePrefs.remove(key);
316 		} else {
317 			fInstanceScopePrefs.putBoolean(key, value);
318 		}
319 	}
320 
321 	/**
322 	 * Associates the specified <code>int</code> value with the specified key in the instance scope
323 	 * or removes the preference if the value is equal to the value in the default scope.
324 	 * <p>
325 	 * This method is intended for use in conjunction with the {@link #getInt(String)} method.
326 	 *
327 	 * @param key <code>key</code> with which the <code>int</code> value is to be associated
328 	 * @param value <code>value</code> to be associated with <code>key</code>
329 	 * @see #getInt(String)
330 	 * @see #getDefaultInt(String)
331 	 * @see #setToDefault(String)
332 	 */
setValueOrRemove(String key, int value)333 	public void setValueOrRemove(String key, int value) {
334 		if (value == getDefaultInt(key)) {
335 			fInstanceScopePrefs.remove(key);
336 		} else {
337 			fInstanceScopePrefs.putInt(key, value);
338 		}
339 	}
340 
341 	/**
342 	 * Associates the specified <code>String</code> value with the specified key in the instance scope
343 	 * or removes the preference if the value is equal to the value in the default scope.
344 	 * <p>
345 	 * This method is intended for use in conjunction with the {@link #getString(String)} method.
346 	 *
347 	 * @param key <code>key</code> with which the <code>String</code> value is to be associated
348 	 * @param value <code>value</code> to be associated with <code>key</code>
349 	 * @see #getString(String)
350 	 * @see #getDefaultString(String)
351 	 * @see #setToDefault(String)
352 	 */
setValueOrRemove(String key, String value)353 	public void setValueOrRemove(String key, String value) {
354 		if (value.equals(getDefaultString(key))) {
355 			fInstanceScopePrefs.remove(key);
356 		} else {
357 			fInstanceScopePrefs.put(key, value);
358 		}
359 	}
360 
361 	/**
362 	 * Forces any changes in the contents of the instance node and its descendants to
363 	 * the persistent store.
364 	 *
365 	 * @throws BackingStoreException if this operation cannot be completed due
366 	 *         to a failure in the backing store, or inability to communicate
367 	 *         with it.
368 	 * @see org.osgi.service.prefs.Preferences#flush()
369 	 */
flush()370 	public void flush() throws BackingStoreException {
371 		fInstanceScopePrefs.flush();
372 	}
373 }
374