| /******************************************************************************* |
| * Copyright (c) 2011, 2018 Wind River Systems, Inc. and others. All rights reserved. |
| * This program and the accompanying materials are made available under the terms |
| * of the Eclipse Public License 2.0 which accompanies this distribution, and is |
| * available at https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Wind River Systems - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.tm.terminal.view.core.preferences; |
| |
| import java.io.OutputStream; |
| import java.util.Map; |
| |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.ISafeRunnable; |
| import org.eclipse.core.runtime.ListenerList; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.SafeRunner; |
| import org.eclipse.core.runtime.preferences.DefaultScope; |
| import org.eclipse.core.runtime.preferences.IEclipsePreferences; |
| import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; |
| import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; |
| import org.eclipse.core.runtime.preferences.IPreferenceFilter; |
| import org.eclipse.core.runtime.preferences.IScopeContext; |
| import org.eclipse.core.runtime.preferences.InstanceScope; |
| import org.osgi.service.prefs.BackingStoreException; |
| |
| /** |
| * Helper class to handle scoped Eclipse preferences for plug-in's. Scoped |
| * preferences means a given preference context plus the default preferences |
| * scope. |
| * <p> |
| * On changes a {@link PreferenceChangeEvent} is sent to inform all listeners of the change. |
| * |
| * @see IEclipsePreferences |
| * @see IEclipsePreferences.PreferenceChangeEvent |
| * @see IEclipsePreferences.IPreferenceChangeListener |
| */ |
| public class ScopedEclipsePreferences { |
| /** |
| * The preferences scope qualifier. |
| */ |
| private final String qualifier; |
| |
| /** |
| * The default scope preference node. |
| */ |
| protected final IEclipsePreferences defaultPrefs; |
| |
| /** |
| * The context scope preference node. |
| */ |
| protected final IEclipsePreferences contextScopePrefs; |
| |
| /** |
| * The registered preference change listeners. |
| */ |
| private final ListenerList listeners = new ListenerList(); |
| |
| /** |
| * Constructor. |
| * <p> |
| * Initialize the scoped preferences with a new instance scope for the given qualifier. The default |
| * scope is determined by calling <code>DefaultScope().getNode(qualifier)</code>. |
| * |
| * @param qualifier The qualifier for the preferences (in example the unique identifier of a plugin). Must not be <code>null</code>. |
| */ |
| public ScopedEclipsePreferences(String qualifier) { |
| this(InstanceScope.INSTANCE, qualifier); |
| } |
| |
| /** |
| * Constructor. |
| * <p> |
| * Initialize the scoped preferences with the given scope. The default scope |
| * is determined by calling <code>DefaultScope().getNode(qualifier)</code>. |
| * |
| * @param context The preference scope context. Must not be <code>null</code>. |
| * @param qualifier The qualifier for the preferences (in example the unique identifier of a plugin). Must not be <code>null</code>. |
| */ |
| public ScopedEclipsePreferences(IScopeContext context, String qualifier) { |
| Assert.isNotNull(context); |
| Assert.isNotNull(qualifier); |
| this.qualifier = qualifier; |
| defaultPrefs = DefaultScope.INSTANCE.getNode(getQualifier()); |
| contextScopePrefs = context.getNode(getQualifier()); |
| } |
| |
| /** |
| * Returns the qualifier that is used to get the preferences. |
| * For plugin preferences, this is the unique identifier of the plugin. |
| */ |
| protected final String getQualifier() { |
| return qualifier; |
| } |
| |
| /** |
| * Exports the preferences to the stream. |
| * <p> |
| * <b>Note:</b> The stream will be closed after the export. |
| * |
| * @param stream The stream to where preferences and defaults should be exported. |
| */ |
| public void exportPreferences(OutputStream stream) { |
| Assert.isNotNull(stream); |
| try { |
| IPreferenceFilter filter = new IPreferenceFilter() { |
| /* (non-Javadoc) |
| * @see org.eclipse.core.runtime.preferences.IPreferenceFilter#getScopes() |
| */ |
| @Override |
| public String[] getScopes() { |
| return new String[] { InstanceScope.SCOPE }; |
| } |
| /* (non-Javadoc) |
| * @see org.eclipse.core.runtime.preferences.IPreferenceFilter#getMapping(java.lang.String) |
| */ |
| @Override |
| public Map getMapping(String scope) { |
| return null; |
| } |
| }; |
| |
| Platform.getPreferencesService().exportPreferences(contextScopePrefs, new IPreferenceFilter[] { filter }, stream); |
| stream.close(); |
| } |
| catch (Exception e) { |
| } |
| } |
| |
| /** |
| * Check whether a key is set or not. |
| * |
| * @param key The key to check. |
| * @return <code>null</code> if the key does not exist. |
| */ |
| public boolean containsKey(String key) { |
| return Platform.getPreferencesService().getString(getQualifier(), key, null, null) != null; |
| } |
| |
| /** |
| * Get a String preference value. |
| * |
| * @param key The preference key. |
| * @return The value of the preference key or the default value if not set. |
| */ |
| public final String getString(String key) { |
| return Platform.getPreferencesService().getString(getQualifier(), key, null, null); |
| } |
| |
| /** |
| * Get a boolean preference value. |
| * |
| * @param key The preference key. |
| * @return The value of the preference key or the default value if not set. |
| */ |
| public final boolean getBoolean(String key) { |
| return Platform.getPreferencesService().getBoolean(getQualifier(), key, false, null); |
| } |
| |
| /** |
| * Get an int preference value. |
| * |
| * @param key The preference key. |
| * @return The value of the preference key or the default value if not set. |
| */ |
| public final int getInt(String key) { |
| return Platform.getPreferencesService().getInt(getQualifier(), key, 0, null); |
| } |
| |
| /** |
| * Get a long preference value. |
| * |
| * @param key The preference key. |
| * @return The value of the preference key or the default value if not set. |
| */ |
| public final long getLong(String key) { |
| return Platform.getPreferencesService().getLong(getQualifier(), key, 0, null); |
| } |
| |
| /** |
| * Get a default String preference value. |
| * |
| * @param key The preference key. |
| * @return The default value of the preference key or <code>null</code>. |
| */ |
| public final String getDefaultString(String key) { |
| return defaultPrefs.get(key, null); |
| } |
| |
| /** |
| * Get a default boolean preference value. |
| * |
| * @param key The preference key. |
| * @return The default value of the preference key or <code>null</code>. |
| */ |
| public final boolean getDefaultBoolean(String key) { |
| return defaultPrefs.getBoolean(key, false); |
| } |
| |
| /** |
| * Get a default int preference value. |
| * |
| * @param key The preference key. |
| * @return The default value of the preference key or <code>null</code>. |
| */ |
| public final int getDefaultInt(String key) { |
| return defaultPrefs.getInt(key, 0); |
| } |
| |
| /** |
| * Get a default long preference value. |
| * |
| * @param key The preference key. |
| * @return The default value of the preference key or <code>null</code>. |
| */ |
| public final long getDefaultLong(String key) { |
| return defaultPrefs.getLong(key, 0); |
| } |
| |
| /** |
| * Set a String preference value. If the value is <code>null</code> or is equal to |
| * the default value, the entry will be removed. |
| * <p> |
| * A {@link PreferenceChangeEvent} is fired, if the value has changed. |
| * |
| * @param key The preference key. |
| * @return The value of the preference key. |
| */ |
| public void putString(String key, String value) { |
| String defValue = defaultPrefs.get(key, null); |
| String instValue = getString(key); |
| if (value == null || value.equals(defValue)) { |
| contextScopePrefs.remove(key); |
| flushAndNotify(contextScopePrefs, key, instValue, defValue); |
| } |
| else if (!value.equals(instValue)) { |
| contextScopePrefs.put(key, value); |
| flushAndNotify(contextScopePrefs, key, instValue, value); |
| } |
| } |
| |
| /** |
| * Set a boolean preference value. If the value is equal the default value, |
| * the entry will be removed. |
| * <p> |
| * A {@link PreferenceChangeEvent} is fired, if the value has changed. |
| * |
| * @param key The preference key. |
| * @return The value of the preference key. |
| */ |
| public void putBoolean(String key, boolean value) { |
| boolean defValue = defaultPrefs.getBoolean(key, false); |
| boolean instValue = getBoolean(key); |
| if (value == defValue) { |
| contextScopePrefs.remove(key); |
| flushAndNotify(contextScopePrefs, key, Boolean.toString(instValue), Boolean.toString(defValue)); |
| } |
| else if (value != instValue) { |
| contextScopePrefs.putBoolean(key, value); |
| flushAndNotify(contextScopePrefs, key, Boolean.toString(instValue), Boolean.toString(value)); |
| } |
| } |
| |
| /** |
| * Set an int preference value. If the value is equal to the default value, |
| * the entry will be removed. |
| * <p> |
| * A {@link PreferenceChangeEvent} is fired, if the value has changed. The old |
| * and new values are string representation in base 10. |
| * |
| * @param key The preference key. |
| * @return The value of the preference key. |
| */ |
| public void putInt(String key, int value) { |
| int defValue = defaultPrefs.getInt(key, 0); |
| int instValue = getInt(key); |
| if (value == defValue) { |
| contextScopePrefs.remove(key); |
| flushAndNotify(contextScopePrefs, key, Integer.toString(instValue), Integer.toString(defValue)); |
| } |
| else if (value != instValue) { |
| contextScopePrefs.putInt(key, value); |
| flushAndNotify(contextScopePrefs, key, Integer.toString(instValue), Integer.toString(value)); |
| } |
| } |
| |
| /** |
| * Set a long preference value. If the given value is equal to the default |
| * value, the entry will be removed. |
| * <p> |
| * A {@link PreferenceChangeEvent} is fired, if the value has changed. The old |
| * and new values are string representation in base 10. |
| * |
| * @param key The preference key. |
| * @return The value of the preference key. |
| */ |
| public void putLong(String key, long value) { |
| long defValue = defaultPrefs.getLong(key, 0); |
| long instValue = getLong(key); |
| if (value == defValue) { |
| contextScopePrefs.remove(key); |
| flushAndNotify(contextScopePrefs, key, Long.toString(instValue), Long.toString(defValue)); |
| } |
| else if (value != instValue) { |
| contextScopePrefs.putLong(key, value); |
| flushAndNotify(contextScopePrefs, key, Long.toString(instValue), Long.toString(value)); |
| } |
| } |
| |
| /** |
| * Set a default String preference value. If the given value is <code>null</code>, |
| * the entry will be removed. |
| * <p> |
| * A {@link PreferenceChangeEvent} is fired, if the value has changed. |
| * |
| * @param key The preference key. |
| * @return The default value of the preference key. |
| */ |
| public void putDefaultString(String key, String value) { |
| String defValue = defaultPrefs.get(key, null); |
| if (value == null) { |
| defaultPrefs.remove(key); |
| flushAndNotify(defaultPrefs, key, defValue, null); |
| } |
| else if (!value.equals(defValue)) { |
| defaultPrefs.put(key, value); |
| flushAndNotify(defaultPrefs, key, defValue, value); |
| } |
| } |
| |
| /** |
| * Set a default boolean preference value. |
| * <p> |
| * A {@link PreferenceChangeEvent} is fired, if the value has changed. |
| * |
| * @param key The preference key. |
| * @return The default value of the preference key. |
| */ |
| public void putDefaultBoolean(String key, boolean value) { |
| boolean defValue = defaultPrefs.getBoolean(key, false); |
| if (value != defValue) { |
| defaultPrefs.putBoolean(key, value); |
| flushAndNotify(defaultPrefs, key, Boolean.toString(defValue), Boolean.toString(value)); |
| } |
| } |
| |
| /** |
| * Set a default int preference value. |
| * <p> |
| * A {@link PreferenceChangeEvent} is fired, if the value has changed. The old |
| * and new values are string representation in base 10. |
| * |
| * @param key The preference key. |
| * @return The default value of the preference key. |
| */ |
| public void putDefaultInt(String key, int value) { |
| int defValue = defaultPrefs.getInt(key, 0); |
| if (value != defValue) { |
| defaultPrefs.putInt(key, value); |
| flushAndNotify(defaultPrefs, key, Integer.toString(defValue), Integer.toString(value)); |
| } |
| } |
| |
| /** |
| * Set a default long preference value. |
| * <p> |
| * A {@link PreferenceChangeEvent} is fired, if the value has changed. The old |
| * and new values are string representation in base 10. |
| * |
| * @param key The preference key. |
| * @return The default value of the preference key. |
| */ |
| public void putDefaultLong(String key, long value) { |
| long defValue = defaultPrefs.getLong(key, 0); |
| if (value != defValue) { |
| defaultPrefs.putLong(key, value); |
| flushAndNotify(defaultPrefs, key, Long.toString(defValue), Long.toString(value)); |
| } |
| } |
| |
| /** |
| * Write back the changes to the store and notify all listeners about the changed key. |
| * |
| * @param node The preference node which has changed. Must not be <code>null</code>. |
| * @param key The key of the changed preference. Must not be <code>null</code>. |
| * @param oldValue The old value as a {@link String}, or <code>null</code>. |
| * @param newValue The new value as a {@link String}, or <code>null</code>. |
| */ |
| protected final void flushAndNotify(IEclipsePreferences node, String key, String oldValue, String newValue) { |
| // Flush the preferences to the persistence store |
| try { node.flush(); } catch (BackingStoreException e) { /* Ignored on purpose */ } |
| |
| // Notify the listeners |
| firePreferenceEvent(node, key, oldValue, newValue); |
| } |
| |
| /** |
| * Register the given listener to receive notifications of preference changes to this node. |
| * Calling this method multiple times with the same listener has no effect. The given listener |
| * argument must not be <code>null</code>. |
| * |
| * @param listener The preference change listener. Must not be <code>null</code>. |
| */ |
| public void addPreferenceChangeListener(IPreferenceChangeListener listener) { |
| Assert.isNotNull(listener); |
| listeners.add(listener); |
| } |
| |
| /** |
| * De-register the given listener from receiving notifications of preference changes |
| * to this node. Calling this method multiple times with the same listener has no |
| * effect. The given listener argument must not be <code>null</code>. |
| * |
| * @param listener The preference change listener. Must not be <code>null</code>. |
| */ |
| public void removePreferenceChangeListener(IPreferenceChangeListener listener) { |
| Assert.isNotNull(listener); |
| listeners.remove(listener); |
| } |
| |
| /** |
| * Convenience method for notifying the registered preference change listeners. |
| * |
| * @param node The preference node which has changed. Must not be <code>null</code>. |
| * @param key The key of the changed preference. Must not be <code>null</code>. |
| * @param oldValue The old value as a {@link String}, or <code>null</code>. |
| * @param newValue The new value as a {@link String}, or <code>null</code>. |
| */ |
| protected void firePreferenceEvent(IEclipsePreferences node, String key, String oldValue, String newValue) { |
| Assert.isNotNull(node); |
| Assert.isNotNull(key); |
| |
| // If no listener is registered, we are done here |
| if (listeners.isEmpty()) return; |
| |
| // Get the list or currently registered listeners |
| Object[] l = listeners.getListeners(); |
| // Create the preference change event |
| final PreferenceChangeEvent event = new PreferenceChangeEvent(node, key, oldValue, newValue); |
| for (int i = 0; i < l.length; i++) { |
| final IPreferenceChangeListener listener = (IPreferenceChangeListener) l[i]; |
| ISafeRunnable job = new ISafeRunnable() { |
| @Override |
| public void handleException(Throwable exception) { |
| // already logged in Platform#run() |
| } |
| |
| @Override |
| public void run() throws Exception { |
| listener.preferenceChange(event); |
| } |
| }; |
| SafeRunner.run(job); |
| } |
| } |
| |
| } |