blob: 8112715b6ed5c27c37ed28cf6aa34e5a8c30c442 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2012, 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.databinding.core;
import java.util.ArrayList;
import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.observable.IChangeListener;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.ObservableTracker;
import org.eclipse.core.databinding.observable.list.IListChangeListener;
import org.eclipse.core.databinding.observable.list.ListChangeEvent;
import org.eclipse.core.databinding.observable.list.ListDiffEntry;
import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
@NonNullByDefault
public class DataBindingSubContext {
private final DataBindingContext dbc;
private final ArrayList<Binding> bindings;
private final ArrayList<IObservable> observables;
private final @Nullable IChangeListener listener;
private boolean enabled= true;
public DataBindingSubContext(final DataBindingContext dbc,
final @Nullable IChangeListener listener) {
this.dbc= dbc;
this.bindings= new ArrayList<>(8);
this.observables= new ArrayList<>(8);
this.listener= listener;
}
public DataBindingSubContext(final DataBindingContext dbc) {
this(dbc, null);
}
public DataBindingContext getDataBindingContext() {
return this.dbc;
}
public void run(final Runnable runnable) {
final IListChangeListener<Binding> bindingsListener= new IListChangeListener<Binding>() {
@Override
public void handleListChange(final ListChangeEvent<? extends Binding> event) {
for (final ListDiffEntry<? extends Binding> diff : event.diff.getDifferences()) {
if (diff.isAddition()) {
addBinding(diff.getElement());
}
else {
removeBinding(diff.getElement());
}
}
}
};
this.dbc.getBindings().addListChangeListener(bindingsListener);
try {
final @NonNull IObservable[] observables= ObservableTracker.runAndCollect(runnable);
this.observables.ensureCapacity(this.observables.size() + observables.length);
for (int i= 0; i < observables.length; i++) {
this.observables.add(observables[i]);
}
}
finally {
this.dbc.getBindings().removeListChangeListener(bindingsListener);
}
}
protected void addBinding(final Binding binding) {
this.bindings.add(binding);
if (this.listener != null) {
binding.getTarget().addChangeListener(this.listener);
}
}
protected void removeBinding(final Binding binding) {
this.bindings.add(binding);
if (this.listener != null) {
binding.getTarget().addChangeListener(this.listener);
}
}
public void setEnabled(final boolean enabled) {
if (enabled == this.enabled) {
return;
}
this.enabled= enabled;
if (this.enabled) {
for (final Binding binding : this.bindings) {
this.dbc.addBinding(binding);
}
}
else {
for (final Binding binding : this.bindings) {
this.dbc.removeBinding(binding);
}
}
}
public void dispose() {
for (final Binding binding : this.bindings) {
if (!binding.isDisposed()) {
binding.dispose();
}
}
this.bindings.clear();
for (final IObservable observable : this.observables) {
if (!observable.isDisposed()) {
observable.dispose();
}
}
this.observables.clear();
}
}