package at.bestsolution.efxclipse.runtime.example.photoedit.ui;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import javafx.beans.InvalidationListener;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
public class EMFListHelper {
static class WrappedList<T> implements ObservableList<T> {
private EObject owner;
private final EList<T> wrappedList;
private List<InvalidationListener> invalidationListeners;
private List<ListChangeListener<? super T>> changeListeners;
private Adapter emfAdapter;
@SuppressWarnings("unchecked")
public WrappedList(EStructuralFeature feature, EObject owner) {
this.wrappedList = (EList<T>) owner.eGet(feature);
this.owner = owner;
}
@Override
public int size() {
return wrappedList.size();
}
@Override
public boolean isEmpty() {
return wrappedList.isEmpty();
}
@Override
public boolean contains(Object o) {
return wrappedList.contains(o);
}
@Override
public Iterator<T> iterator() {
return wrappedList.iterator();
}
@Override
public Object[] toArray() {
return wrappedList.toArray();
}
@Override
public <V> V[] toArray(V[] a) {
return wrappedList.toArray(a);
}
@Override
public boolean add(T e) {
return wrappedList.add(e);
}
@Override
public boolean remove(Object o) {
return wrappedList.remove(o);
}
@Override
public boolean containsAll(Collection<?> c) {
return wrappedList.containsAll(c);
}
@Override
public boolean addAll(Collection<? extends T> c) {
return wrappedList.addAll(c);
}
@Override
public boolean addAll(int index, Collection<? extends T> c) {
return wrappedList.addAll(index, c);
}
@Override
public boolean removeAll(Collection<?> c) {
return wrappedList.removeAll(c);
}
@Override
public boolean retainAll(Collection<?> c) {
return wrappedList.removeAll(c);
}
@Override
public void clear() {
wrappedList.clear();
}
@Override
public T get(int index) {
return wrappedList.get(index);
}
@Override
public T set(int index, T element) {
return wrappedList.set(index, element);
}
@Override
public void add(int index, T element) {
wrappedList.add(index, element);
}
@Override
public T remove(int index) {
return wrappedList.remove(index);
}
@Override
public int indexOf(Object o) {
return wrappedList.indexOf(o);
}
@Override
public int lastIndexOf(Object o) {
return wrappedList.lastIndexOf(o);
}
@Override
public ListIterator<T> listIterator() {
return wrappedList.listIterator();
}
@Override
public ListIterator<T> listIterator(int index) {
return wrappedList.listIterator(index);
}
@Override
public List<T> subList(int fromIndex, int toIndex) {
return wrappedList.subList(fromIndex, toIndex);
}
@Override
public boolean addAll(T... elements) {
return wrappedList.addAll(Arrays.asList(elements));
}
@Override
public void remove(int from, int to) {
//TODO Improve performance??
for( int idx = to; idx >= from; idx-- ) {
wrappedList.remove(idx);
}
}
@Override
public boolean removeAll(T... elements) {
return wrappedList.removeAll(Arrays.asList(elements));
}
@Override
public boolean retainAll(T... elements) {
return wrappedList.retainAll(Arrays.asList(elements));
}
@Override
public boolean setAll(T... elements) {
//TODO Improve performance
wrappedList.clear();
return wrappedList.addAll(Arrays.asList(elements));
}
@Override
public boolean setAll(Collection<? extends T> col) {
//TODO Improve performance
wrappedList.clear();
return wrappedList.addAll(col);
}
@Override
public void addListener(InvalidationListener listener) {
if( invalidationListeners == null ) {
invalidationListeners = new ArrayList<InvalidationListener>();
}
invalidationListeners.add(listener);
handleEMFAdapter();
}
@Override
public void addListener(ListChangeListener<? super T> listener) {
if( changeListeners == null ) {
changeListeners = new ArrayList<ListChangeListener<? super T>>();
}
changeListeners.add(listener);
handleEMFAdapter();
}
@Override
public void removeListener(InvalidationListener listener) {
if( invalidationListeners != null ) {
invalidationListeners.remove(listener);
if( invalidationListeners.isEmpty() ) {
invalidationListeners = null;
}
}
handleEMFAdapter();
}
@Override
public void removeListener(ListChangeListener<? super T> listener) {
if( changeListeners == null ) {
changeListeners.remove(listener);
if( changeListeners.isEmpty() ) {
changeListeners = null;
}
}
handleEMFAdapter();
}
private void handleEMFAdapter() {
if( changeListeners != null || invalidationListeners != null ) {
if( emfAdapter == null ) {
emfAdapter = new AdapterImpl() {
};
owner.eAdapters().add(emfAdapter);
}
} else {
if( emfAdapter != null ) {
owner.eAdapters().remove(emfAdapter);
emfAdapter = null;
}
}
}
}
public static <T> ObservableList<T> adaptList(EStructuralFeature feature, EObject owner) {
return new WrappedList<T>(feature, owner);
}
}