Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.javafx.collections;
import java.util.*;
import javafx.beans.InvalidationListener;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import javafx.util.Callback;
public abstract class VetoableListDecorator implements ObservableList {
private final ObservableList list;
private int modCount;
private ListListenerHelper helper;
private static interface ModCountAccessor {
public int get();
public int incrementAndGet();
}
/**
* The type of the change can be observed from the combination of arguments.
*
*
If something is going to be added toBeAdded is non-empty
* and indexes contain two indexes that are pointing to the position, e.g. {2, 2}
*
If something is going to be removed, the indexes are paired by two:
* from(inclusive)-to(exclusive) and are pointing to the current list.
* E.g. if we remove 2,3,5 from list {0,1,2,3,4,5}, the indexes
* will be {2, 4, 5, 6}. If there's more than one pair of indexes, toBeAdded is always empty.
*
for set toBeAdded contains 1 element and indexes are like with removal: {index, index + 1}
*
for setAll, toBeAdded contains all new elements and indexes looks like this: {0, size()}
*
*
* Note that it's always safe to iterate over toBeAdded and use indexes as pairs of
* from-to, as there's always at least one pair.
*
* @param toBeAdded the list to be added
* @throws IllegalArgumentException when the change is vetoed
*/
protected abstract void onProposedChange(List toBeAdded, int... indexes);
public VetoableListDecorator(ObservableList decorated) {
this.list = decorated;
this.list.addListener(new ListChangeListener() {
@Override
public void onChanged(ListChangeListener.Change c) {
ListListenerHelper.fireValueChangedEvent(helper,
new SourceAdapterChange(VetoableListDecorator.this, c));
}
});
}
@Override
public void addListener(ListChangeListener listener) {
helper = ListListenerHelper.addListener(helper, listener);
}
@Override
public void removeListener(ListChangeListener listener) {
helper = ListListenerHelper.removeListener(helper, listener);
}
@Override
public void addListener(InvalidationListener listener) {
helper = ListListenerHelper.addListener(helper, listener);
}
@Override
public void removeListener(InvalidationListener listener) {
helper = ListListenerHelper.removeListener(helper, listener);
}
@Override
public boolean addAll(E... elements) {
return addAll(Arrays.asList(elements));
}
@Override
public boolean setAll(E... elements) {
return setAll(Arrays.asList(elements));
}
@Override
public boolean setAll(Collection col) {
onProposedChange(Collections.unmodifiableList(new ArrayList(col)), 0, size());
boolean ret = list.setAll(col);
modCount++;
return ret;
}
private void removeFromList(List backingList, int offset, Collection col, boolean complement) {
int[] toBeRemoved = new int[2];
int pointer = -1;
for (int i = 0; i < backingList.size(); ++i) {
final E el = backingList.get(i);
if (col.contains(el) ^ complement) {
if (pointer == -1) {
toBeRemoved[pointer + 1] = offset + i;
toBeRemoved[pointer + 2] = offset + i + 1;
pointer += 2;
} else {
if (toBeRemoved[pointer - 1] == offset + i) {
toBeRemoved[pointer - 1] = offset + i + 1;
} else {
int[] tmp = new int[toBeRemoved.length + 2];
System.arraycopy(toBeRemoved, 0, tmp, 0, toBeRemoved.length);
toBeRemoved = tmp;
toBeRemoved[pointer + 1] = offset + i;
toBeRemoved[pointer + 2] = offset + i + 1;
pointer += 2;
}
}
}
}
if (pointer != -1) {
onProposedChange(Collections.emptyList(), toBeRemoved);
}
}
@Override
public boolean removeAll(E... elements) {
return removeAll(Arrays.asList(elements));
}
@Override
public boolean retainAll(E... elements) {
return retainAll(Arrays.asList(elements));
}
@Override
public void remove(int from, int to) {
onProposedChange(Collections.emptyList(), from, to);
list.remove(from, to);
modCount++;
}
@Override
public int size() {
return list.size();
}
@Override
public boolean isEmpty() {
return list.isEmpty();
}
@Override
public boolean contains(Object o) {
return list.contains(o);
}
@Override
public Iterator iterator() {
return new VetoableIteratorDecorator(new ModCountAccessorImpl(),list.iterator(), 0);
}
@Override
public Object[] toArray() {
return list.toArray();
}
@Override
public T[] toArray(T[] a) {
return list.toArray(a);
}
@Override
public boolean add(E e) {
onProposedChange(Collections.singletonList(e), size(), size());
boolean ret = list.add(e);
modCount++;
return ret;
}
@Override
public boolean remove(Object o) {
int i = list.indexOf(o);
if (i != - 1) {
remove(i);
return true;
}
return false;
}
@Override
public boolean containsAll(Collection c) {
return list.containsAll(c);
}
@Override
public boolean addAll(Collection c) {
onProposedChange(Collections.unmodifiableList(new ArrayList(c)), size(), size());
boolean ret = list.addAll(c);
if (ret)
modCount++;
return ret;
}
@Override
public boolean addAll(int index, Collection c) {
onProposedChange(Collections.unmodifiableList(new ArrayList(c)), index, index);
boolean ret = list.addAll(index, c);
if (ret)
modCount++;
return ret;
}
@Override
public boolean removeAll(Collection c) {
removeFromList(this, 0, c, false);
boolean ret = list.removeAll(c);
if (ret)
modCount++;
return ret;
}
@Override
public boolean retainAll(Collection c) {
removeFromList(this, 0, c, true);
boolean ret = list.retainAll(c);
if (ret)
modCount++;
return ret;
}
@Override
public void clear() {
onProposedChange(Collections.emptyList(), 0, size());
list.clear();
modCount++;
}
@Override
public E get(int index) {
return list.get(index);
}
@Override
public E set(int index, E element) {
onProposedChange(Collections.singletonList(element), index, index + 1);
return list.set(index, element);
}
@Override
public void add(int index, E element) {
onProposedChange(Collections.singletonList(element), index, index);
list.add(index, element);
modCount++;
}
@Override
public E remove(int index) {
onProposedChange(Collections.emptyList(), index, index + 1);
E ret = list.remove(index);
modCount++;
return ret;
}
@Override
public int indexOf(Object o) {
return list.indexOf(o);
}
@Override
public int lastIndexOf(Object o) {
return lastIndexOf(o);
}
@Override
public ListIterator listIterator() {
return new VetoableListIteratorDecorator(new ModCountAccessorImpl(), list.listIterator(), 0);
}
@Override
public ListIterator listIterator(int index) {
return new VetoableListIteratorDecorator(new ModCountAccessorImpl(), list.listIterator(index), index);
}
@Override
public List subList(int fromIndex, int toIndex) {
return new VetoableSubListDecorator(new ModCountAccessorImpl(), list.subList(fromIndex, toIndex), fromIndex);
}
@Override
public String toString() {
return list.toString();
}
@Override
public boolean equals(Object obj) {
return list.equals(obj);
}
@Override
public int hashCode() {
return list.hashCode();
}
/**
* Creates a {@link javafx.collections.transformation.FilteredList} wrapper of this list using
* the specified predicate.
* @param predicate the predicate to use
* @return new {@code FilteredList}
*/
public FilteredList filtered(Callback predicate) {
return new FilteredList(this, predicate);
}
/**
* Creates a {@link javafx.collections.transformation.SortedList} wrapper of this list using
* the specified comparator.
* @param comparator the comparator to use or null for the natural order
* @return new {@code SortedList}
*/
public SortedList sorted(Comparator comparator) {
return new SortedList(this, comparator);
}
/**
* Creates a {@link SortedList} wrapper of this list with the natural
* ordering.
* @return new {@code SortedList}
*/
public SortedList sorted() {
return sorted(null);
}
private class VetoableSubListDecorator implements List {
private final List subList;
private final int offset;
private final ModCountAccessor modCountAccessor;
private int modCount;
public VetoableSubListDecorator(ModCountAccessor modCountAccessor, List subList, int offset) {
this.modCountAccessor = modCountAccessor;
this.modCount = modCountAccessor.get();
this.subList = subList;
this.offset = offset;
}
@Override
public int size() {
checkForComodification();
return subList.size();
}
@Override
public boolean isEmpty() {
checkForComodification();
return subList.isEmpty();
}
@Override
public boolean contains(Object o) {
checkForComodification();
return subList.contains(o);
}
@Override
public Iterator iterator() {
checkForComodification();
return new VetoableIteratorDecorator(new ModCountAccessorImplSub(), subList.iterator(), offset);
}
@Override
public Object[] toArray() {
checkForComodification();
return subList.toArray();
}
@Override
public T[] toArray(T[] a) {
checkForComodification();
return subList.toArray(a);
}
@Override
public boolean add(E e) {
checkForComodification();
onProposedChange(Collections.singletonList(e), offset + size(), offset + size());
boolean res = subList.add(e);
incrementModCount();
return res;
}
@Override
public boolean remove(Object o) {
checkForComodification();
int i = indexOf(o);
if (i != -1) {
remove(i);
return true;
}
return false;
}
@Override
public boolean containsAll(Collection c) {
checkForComodification();
return subList.containsAll(c);
}
@Override
public boolean addAll(Collection c) {
checkForComodification();
onProposedChange(Collections.unmodifiableList(new ArrayList(c)), offset + size(), offset + size());
boolean res = subList.addAll(c);
if (res)
incrementModCount();
return res;
}
@Override
public boolean addAll(int index, Collection c) {
checkForComodification();
onProposedChange(Collections.unmodifiableList(new ArrayList(c)), offset + index, offset + index);
boolean res = subList.addAll(index, c);
if (res)
incrementModCount();
return res;
}
@Override
public boolean removeAll(Collection c) {
checkForComodification();
removeFromList(this, offset, c, false);
boolean res = subList.removeAll(c);
if (res)
incrementModCount();
return res;
}
@Override
public boolean retainAll(Collection c) {
checkForComodification();
removeFromList(this, offset, c, true);
boolean res = subList.retainAll(c);
if (res)
incrementModCount();
return res;
}
@Override
public void clear() {
checkForComodification();
onProposedChange(Collections.emptyList(), offset, offset + size());
subList.clear();
incrementModCount();
}
@Override
public E get(int index) {
checkForComodification();
return subList.get(index);
}
@Override
public E set(int index, E element) {
checkForComodification();
onProposedChange(Collections.singletonList(element), offset + index, offset + index + 1);
return subList.set(index, element);
}
@Override
public void add(int index, E element) {
checkForComodification();
onProposedChange(Collections.singletonList(element), offset + index, offset + index);
subList.add(index, element);
incrementModCount();
}
@Override
public E remove(int index) {
checkForComodification();
onProposedChange(Collections.emptyList(), offset + index, offset + index + 1);
E res = subList.remove(index);
incrementModCount();
return res;
}
@Override
public int indexOf(Object o) {
checkForComodification();
return subList.indexOf(o);
}
@Override
public int lastIndexOf(Object o) {
checkForComodification();
return subList.lastIndexOf(o);
}
@Override
public ListIterator listIterator() {
checkForComodification();
return new VetoableListIteratorDecorator(new ModCountAccessorImplSub(),
subList.listIterator(), offset);
}
@Override
public ListIterator listIterator(int index) {
checkForComodification();
return new VetoableListIteratorDecorator(new ModCountAccessorImplSub(),
subList.listIterator(index), offset + index);
}
@Override
public List subList(int fromIndex, int toIndex) {
checkForComodification();
return new VetoableSubListDecorator(new ModCountAccessorImplSub(),
subList.subList(fromIndex, toIndex), offset + fromIndex);
}
@Override
public String toString() {
checkForComodification();
return subList.toString();
}
@Override
public boolean equals(Object obj) {
checkForComodification();
return subList.equals(obj);
}
@Override
public int hashCode() {
checkForComodification();
return subList.hashCode();
}
private void checkForComodification() {
if (modCount != modCountAccessor.get()) {
throw new ConcurrentModificationException();
}
}
private void incrementModCount() {
modCount = modCountAccessor.incrementAndGet();
}
private class ModCountAccessorImplSub implements ModCountAccessor{
@Override
public int get() {
return modCount;
}
@Override
public int incrementAndGet() {
return modCount = modCountAccessor.incrementAndGet();
}
}
}
private class VetoableIteratorDecorator implements Iterator {
private final Iterator it;
private final ModCountAccessor modCountAccessor;
private int modCount;
protected final int offset;
protected int cursor;
protected int lastReturned;
public VetoableIteratorDecorator(ModCountAccessor modCountAccessor, Iterator it, int offset) {
this.modCountAccessor = modCountAccessor;
this.modCount = modCountAccessor.get();
this.it = it;
this.offset = offset;
}
@Override
public boolean hasNext() {
checkForComodification();
return it.hasNext();
}
@Override
public E next() {
checkForComodification();
E e = it.next();
lastReturned = cursor++;
return e;
}
@Override
public void remove() {
checkForComodification();
if (lastReturned == -1) {
throw new IllegalStateException();
}
onProposedChange(Collections.emptyList(), offset + lastReturned, offset + lastReturned + 1);
it.remove();
incrementModCount();
lastReturned = -1;
--cursor;
}
protected void checkForComodification() {
if (modCount != modCountAccessor.get()) {
throw new ConcurrentModificationException();
}
}
protected void incrementModCount() {
modCount = modCountAccessor.incrementAndGet();
}
}
private class VetoableListIteratorDecorator extends VetoableIteratorDecorator implements ListIterator {
private final ListIterator lit;
public VetoableListIteratorDecorator(ModCountAccessor modCountAccessor, ListIterator it, int offset) {
super(modCountAccessor, it, offset);
this.lit = it;
}
@Override
public boolean hasPrevious() {
checkForComodification();
return lit.hasPrevious();
}
@Override
public E previous() {
checkForComodification();
E e = lit.previous();
lastReturned = --cursor;
return e;
}
@Override
public int nextIndex() {
checkForComodification();
return lit.nextIndex();
}
@Override
public int previousIndex() {
checkForComodification();
return lit.previousIndex();
}
@Override
public void set(E e) {
checkForComodification();
if (lastReturned == -1) {
throw new IllegalStateException();
}
onProposedChange(Collections.singletonList(e), offset + lastReturned, offset + lastReturned + 1);
lit.set(e);
}
@Override
public void add(E e) {
checkForComodification();
onProposedChange(Collections.singletonList(e), offset + cursor, offset + cursor);
lit.add(e);
incrementModCount();
++cursor;
}
}
private class ModCountAccessorImpl implements ModCountAccessor {
public ModCountAccessorImpl() {
}
@Override
public int get() {
return modCount;
}
@Override
public int incrementAndGet() {
return ++modCount;
}
}
}