| /*=============================================================================# |
| # Copyright (c) 2006, 2021 Stephan Wahlbrink and others. |
| # |
| # This program and the accompanying materials are made available under the |
| # terms of the Eclipse Public License 2.0 which is available at |
| # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 |
| # which is available at https://www.apache.org/licenses/LICENSE-2.0. |
| # |
| # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 |
| # |
| # Contributors: |
| # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation |
| #=============================================================================*/ |
| |
| package org.eclipse.statet.ecommons.preferences.core.util; |
| |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.osgi.service.prefs.BackingStoreException; |
| import org.osgi.service.prefs.Preferences; |
| |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.jobs.Job; |
| 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.IScopeContext; |
| import org.eclipse.core.runtime.preferences.InstanceScope; |
| |
| import org.eclipse.statet.jcommons.collections.ImCollections; |
| import org.eclipse.statet.jcommons.collections.ImList; |
| import org.eclipse.statet.jcommons.collections.ImSet; |
| import org.eclipse.statet.jcommons.lang.NonNullByDefault; |
| |
| import org.eclipse.statet.ecommons.preferences.core.Preference; |
| import org.eclipse.statet.ecommons.preferences.core.PreferenceAccess; |
| import org.eclipse.statet.ecommons.preferences.core.PreferenceSetService; |
| import org.eclipse.statet.internal.ecommons.preferences.core.ECommonsPreferencesCorePlugin; |
| |
| |
| @NonNullByDefault |
| public final class PreferenceUtils { |
| |
| |
| private static class DefaultImpl implements PreferenceAccess { |
| |
| private final ImList<IScopeContext> contexts; |
| |
| |
| private DefaultImpl(final ImList<IScopeContext> contexts) { |
| this.contexts= contexts; |
| } |
| |
| |
| @Override |
| public ImList<IScopeContext> getPreferenceContexts() { |
| return this.contexts; |
| } |
| |
| @Override |
| public <T> T getPreferenceValue(final Preference<T> pref) { |
| return PreferenceUtils.getPrefValue(this.contexts, pref); |
| } |
| |
| @Override |
| public void addPreferenceNodeListener(final String nodeQualifier, final IPreferenceChangeListener listener) { |
| for (int i= 0; i < this.contexts.size(); i++) { |
| final IScopeContext context= this.contexts.get(i); |
| if (context instanceof DefaultScope) { |
| continue; |
| } |
| final IEclipsePreferences node= context.getNode(nodeQualifier); |
| if (node != null) { |
| node.addPreferenceChangeListener(listener); |
| } |
| } |
| } |
| |
| @Override |
| public void removePreferenceNodeListener(final String nodeQualifier, final IPreferenceChangeListener listener) { |
| for (int i= 0; i < this.contexts.size(); i++) { |
| final IScopeContext context= this.contexts.get(i); |
| if (context instanceof DefaultScope) { |
| continue; |
| } |
| final IEclipsePreferences node= context.getNode(nodeQualifier); |
| if (node != null) { |
| node.removePreferenceChangeListener(listener); |
| } |
| } |
| } |
| |
| @Override |
| public void addPreferenceSetListener(final PreferenceSetService.ChangeListener listener, |
| final ImSet<String> qualifiers) { |
| getPreferenceSetService().addChangeListener(listener, |
| getPreferenceContexts(), qualifiers ); |
| } |
| |
| @Override |
| public void removePreferenceSetListener(final PreferenceSetService.ChangeListener listener) { |
| final PreferenceSetService service= getPreferenceSetService(); |
| if (service != null) { |
| service.removeChangeListener(listener); |
| } |
| } |
| |
| } |
| |
| private static class MapImpl implements PreferenceAccess { |
| |
| |
| private final Map<Preference<?>, Object> preferencesMap; |
| |
| MapImpl(final Map<Preference<?>, Object> preferencesMap) { |
| this.preferencesMap= preferencesMap; |
| } |
| |
| @Override |
| public ImList<IScopeContext> getPreferenceContexts() { |
| return ImCollections.emptyList(); |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public <T> T getPreferenceValue(final Preference<T> pref) { |
| return (T) this.preferencesMap.get(pref); |
| } |
| |
| /** |
| * Not (yet) supported |
| */ |
| @Override |
| public void addPreferenceNodeListener(final String nodeQualifier, final IPreferenceChangeListener listener) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| /** |
| * Not (yet) supported |
| */ |
| @Override |
| public void removePreferenceNodeListener(final String nodeQualifier, final IPreferenceChangeListener listener) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| /** |
| * Not (yet) supported |
| */ |
| @Override |
| public void addPreferenceSetListener(final PreferenceSetService.ChangeListener listener, |
| final ImSet<String> qualifiers) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| /** |
| * Not (yet) supported |
| */ |
| @Override |
| public void removePreferenceSetListener(final PreferenceSetService.ChangeListener listener) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| } |
| |
| |
| private final static DefaultImpl DEFAULT_PREFS= new DefaultImpl(ImCollections.newList( |
| DefaultScope.INSTANCE )); |
| |
| private final static DefaultImpl INSTANCE_PREFS= new DefaultImpl(ImCollections.newList( |
| InstanceScope.INSTANCE, |
| DefaultScope.INSTANCE )); |
| |
| |
| public final static PreferenceAccess getInstancePrefs() { |
| return INSTANCE_PREFS; |
| } |
| |
| public final static PreferenceAccess getDefaultPrefs() { |
| return DEFAULT_PREFS; |
| } |
| |
| |
| public static PreferenceAccess createAccess(final Map<Preference<?>, Object> preferencesMap) { |
| return new MapImpl(preferencesMap); |
| } |
| |
| public static PreferenceAccess createAccess(final List<IScopeContext> contexts) { |
| return new DefaultImpl(ImCollections.toList(contexts)); |
| } |
| |
| |
| public static final int FLUSH_SYNC= 1 << 0; |
| public static final int FLUSH_ASYNC= 1 << 1; |
| |
| |
| public static <T> T getPrefValue(final List<IScopeContext> contexts, final Preference<T> pref) { |
| String storeValue= null; |
| for (int i= 0; i < contexts.size() && storeValue == null; i++) { |
| try { |
| storeValue= contexts.get(i).getNode(pref.getQualifier()).get(pref.getKey(), null); |
| } |
| catch (final IllegalStateException e) { |
| } |
| } |
| return pref.store2Usage(storeValue); |
| } |
| |
| public static <T> T getPrefValue(final IScopeContext context, final Preference<T> pref) { |
| final IEclipsePreferences node= context.getNode(pref.getQualifier()); |
| return getPrefValue(node, pref); |
| } |
| |
| public static <T> T getPrefValue(final IEclipsePreferences node, final Preference<T> pref) { |
| final String storeValue= node.get(pref.getKey(), (String) null); |
| return pref.store2Usage(storeValue); |
| } |
| |
| public static <T> void setPrefValue(final IScopeContext context, |
| final Preference<T> pref, final T value) { |
| final IEclipsePreferences node= context.getNode(pref.getQualifier()); |
| setPrefValue(node, pref, value); |
| } |
| |
| public static <T> void setPrefValue(final IScopeContext context, |
| final Preference<T> pref, final T value, final int flags) { |
| final IEclipsePreferences node= context.getNode(pref.getQualifier()); |
| setPrefValue(node, pref, value); |
| |
| if ((flags & FLUSH_SYNC) != 0) { |
| flush(node); |
| } |
| else if ((flags & FLUSH_ASYNC) != 0) { |
| final Job job= new Job("Save Preferences") { |
| @Override |
| protected IStatus run(final IProgressMonitor monitor) { |
| flush(node); |
| return Status.OK_STATUS; |
| } |
| }; |
| job.setSystem(true); |
| job.setUser(false); |
| job.setPriority(Job.SHORT); |
| job.schedule(); |
| } |
| } |
| |
| private static void flush(final Preferences node) { |
| try { |
| node.flush(); |
| } |
| catch (final BackingStoreException e) { |
| ECommonsPreferencesCorePlugin.log(new Status(IStatus.ERROR, |
| ECommonsPreferencesCorePlugin.BUNDLE_ID, |
| "An error occurred when saving preferences.", //$NON-NLS-1$ |
| e )); |
| } |
| } |
| |
| @SuppressWarnings({ "rawtypes", "unchecked" }) |
| public static void setPrefValues(final IScopeContext context, |
| final Map<Preference<?>, Object> preferencesMap) { |
| for (final Map.Entry<Preference<?>, Object> pref : preferencesMap.entrySet()) { |
| setPrefValue(context, (Preference) pref.getKey(), pref.getValue()); |
| } |
| } |
| |
| public static <T> void setPrefValue(final IEclipsePreferences node, |
| final Preference<T> pref, final T value) { |
| final String storeValue; |
| if (value == null |
| || (storeValue= pref.usage2Store(value)) == null) { |
| node.remove(pref.getKey()); |
| return; |
| } |
| node.put(pref.getKey(), storeValue); |
| } |
| |
| |
| public static PreferenceSetService getPreferenceSetService() { |
| // Adapt this if used in other context |
| final ECommonsPreferencesCorePlugin plugin= ECommonsPreferencesCorePlugin.getInstance(); |
| if (plugin != null) { |
| return plugin.getPreferenceSetService(); |
| } |
| return null; |
| } |
| |
| } |