| /*=============================================================================# |
| # Copyright (c) 2015, 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.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; |
| import org.eclipse.core.runtime.preferences.IScopeContext; |
| |
| 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.ecommons.preferences.core.PreferenceSetService.ChangeListener; |
| |
| |
| @NonNullByDefault |
| public class PreferenceAccessWrapper implements PreferenceAccess { |
| |
| |
| private static class ListenerItem { |
| |
| private final PreferenceSetService.ChangeListener listener; |
| |
| private ImSet<String> qualifiers; |
| |
| |
| public ListenerItem(final PreferenceSetService.ChangeListener listener, |
| final ImSet<String> qualifiers) { |
| this.listener= listener; |
| this.qualifiers= qualifiers; |
| } |
| |
| } |
| |
| |
| private volatile boolean isDisposed; |
| |
| private volatile ImList<IScopeContext> contexts; |
| |
| private final List<ListenerItem> listeners= new ArrayList<>(); |
| |
| |
| public PreferenceAccessWrapper(final ImList<IScopeContext> contexts) { |
| this.contexts= contexts; |
| } |
| |
| public PreferenceAccessWrapper() { |
| this.contexts= ImCollections.emptyList(); |
| } |
| |
| |
| public synchronized void setPreferenceContexts(final ImList<IScopeContext> contexts) { |
| if (isDisposed() || this.contexts.equals(contexts)) { |
| return; |
| } |
| |
| this.contexts= contexts; |
| |
| final PreferenceSetService service= PreferenceUtils.getPreferenceSetService(); |
| if (service != null) { |
| synchronized (this.listeners) { |
| final int l= this.listeners.size(); |
| for (int i= 0; i < l; i++) { |
| final ListenerItem item= this.listeners.get(i); |
| service.addChangeListener(item.listener, |
| contexts, item.qualifiers ); |
| } |
| } |
| } |
| } |
| |
| public synchronized void dispose() { |
| if (isDisposed()) { |
| return; |
| } |
| |
| this.isDisposed= true; |
| |
| this.contexts= ImCollections.emptyList(); |
| |
| final PreferenceSetService service= PreferenceUtils.getPreferenceSetService(); |
| if (service != null) { |
| synchronized (this.listeners) { |
| final int l= this.listeners.size(); |
| for (int i= 0; i < l; i++) { |
| final ListenerItem item= this.listeners.get(i); |
| service.removeChangeListener(item.listener); |
| } |
| this.listeners.clear(); |
| } |
| } |
| } |
| |
| public final boolean isDisposed() { |
| return this.isDisposed; |
| } |
| |
| |
| @Override |
| public final ImList<IScopeContext> getPreferenceContexts() { |
| return this.contexts; |
| } |
| |
| @Override |
| public final <T> T getPreferenceValue(final Preference<T> pref) { |
| return PreferenceUtils.getPrefValue(this.contexts, pref); |
| } |
| |
| @Override |
| public void addPreferenceNodeListener(final String nodeQualifier, final IPreferenceChangeListener listener) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void removePreferenceNodeListener(final String nodeQualifier, final IPreferenceChangeListener listener) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void addPreferenceSetListener(final ChangeListener listener, final ImSet<String> qualifiers) { |
| if (listener == null) { |
| throw new NullPointerException("listener"); //$NON-NLS-1$ |
| } |
| if (qualifiers == null) { |
| throw new NullPointerException("qualifiers"); //$NON-NLS-1$ |
| } |
| |
| LISTENER: synchronized (this.listeners) { |
| if (isDisposed()) { |
| return; |
| } |
| |
| final int l= this.listeners.size(); |
| for (int i= 0; i < l; i++) { |
| final ListenerItem item= this.listeners.get(i); |
| if (item.listener == listener) { |
| if (item.qualifiers.equals(qualifiers)) { |
| return; |
| } |
| item.qualifiers= qualifiers; |
| break LISTENER; |
| } |
| } |
| this.listeners.add(new ListenerItem(listener, qualifiers)); |
| } |
| |
| final PreferenceSetService service= PreferenceUtils.getPreferenceSetService(); |
| if (service != null) { |
| synchronized (this) { |
| if (isDisposed()) { |
| return; |
| } |
| |
| service.addChangeListener(listener, |
| this.contexts, qualifiers ); |
| } |
| } |
| } |
| |
| @Override |
| public void removePreferenceSetListener(final ChangeListener listener) { |
| LISTENER: synchronized (this.listeners) { |
| if (isDisposed()) { |
| return; |
| } |
| |
| final int l= this.listeners.size(); |
| for (int i= 0; i < l; i++) { |
| final ListenerItem item= this.listeners.get(i); |
| if (item.listener == listener) { |
| this.listeners.remove(i); |
| break LISTENER; |
| } |
| } |
| return; |
| } |
| |
| final PreferenceSetService service= PreferenceUtils.getPreferenceSetService(); |
| if (service != null) { |
| service.removeChangeListener(listener); |
| } |
| } |
| |
| } |